在 CloudSearch 上使用 PHP 的 AWS SDK 查找带前缀的短语

Find phrase with prefix with AWS SDK for PHP on CloudSearch

在我们的后台,我们将使用 Cloudsearch 作为搜索部分,而不是一些 Mysql 请求。

问题是我在使用 Cloudsearch 获得相同结果时遇到了一些问题,如果可能的话我希望得到一些帮助...

例如,如果用户搜索“Alexandre Call”:

With Mysql :名为“Alexandre & blablabla Call[= 的事件的一个结果75=]XXX

有关更多信息,Mysql 请求使用一些 ... WHERE CONCAT(FIELD1, " ", FIELD2, " ", FIELD 3) LIKE '%alexandre%' AND CONCAT(FIELD1, " ", FIELD2, " ", FIELD 3) LIKE '%call%' 作为我的示例。

使用 Cloudsearch:280 个结果,事件包含“Alexandre”或事件包含“call" 或带后缀的词 "call + something"

这就是我将 Cloudsearch 与 AWS SDK for PHP 一起使用的方式:

1/ 我连接到我的搜索域:

$client = CloudSearchDomainClient::factory(array(
    'endpoint' => 'https://XXXXXXXX.eu-west-1.cloudsearch.amazonaws.com',
    'validation' => false,
    'version' => 'latest',
    'credentials' => [
        'key'    => _S3_API_KEY_,
        'secret' => _S3_API_SECRET_,
    ],
    'region' =>  'eu-west-1',
));

2/我的研究:

$search_result['event'] = $client->search(
    array(
        // This is what user search, in my example $query = "Alexandre Call"
        'query'        => $query, 
        'queryOptions' => '{
                             "defaultOperator" : "or",
                             "fields":["description","nomevent^3", "idftpevent^2"]
                           }',
        'queryParser'  => 'simple',
        'size'         => 500,
        'start'        => 0
    )
);

有了这个,我得到了 280 个结果,正如我所说的...知道如何获得与 mysql 相似的结果吗?

编辑:

我想我想搜索这样的东西,但我不知道如何搜索:

(and 
  (or description='alexandre' nomevent='alexandre' idftpevent='alexandre') 
  (or description='call' nomevent='call' idftpevent='call')
)

但不可能让它发挥作用...我的想法应该是在我搜索的 3 个字段中至少有一次 alexandrecall 也是如此(对于像调用、调用、 callXXX...),有什么想法吗?

编辑 2 :

我为我的示例尝试了解决方案:

$event_query = 'alexander* call*';

$search_result['event'] = $client->search(
    array(
        'query'        => $event_query,
        'queryOptions' => '{
                               "defaultOperator": "and",
                               "fields":["nomevent^3","idftpevent^2", "description"]
                           }',
        'queryParser'  => 'simple',
        'size'         => 500,
        'start'        => 0
    )
);

但是我没有得到结果...我做错了什么?

我不太明白"defaultOperator": "and",是干什么用的?这意味着我搜索 alexandre* AND call* 或者这意味着我在我提到的 3 个字段中搜索 alexandre*call*

正如我之前展示的,我想在我提到的 3 个字段之一中搜索 alexandre* 并且在我提到的 3 个字段中的至少一个中搜索 call*

I think I'd like to search something like this but I don't know how :

(and 
  (or description='alexandre' nomevent='alexandre' idftpevent='alexandre') 
  (or description='call' nomevent='call' idftpevent='call')
)

这非常接近,但我认为您可以通过利用 simple 查询解析器中的内置运算符来大大简化。使用该解析器,前缀查询在单词或短语的末尾使用 * 来指示您正在搜索以前面的字符开头的匹配项。所以您的查询应该类似于以下之一:

/* Only treat the last word as a prefix */

alexandre call*

/* Treat each word as a prefix */

alexandre* call*

现在,要匹配您尝试的复合查询的 and 逻辑,您只需将 defaultOperator 更改为 and(或删除该选项,因为 and 是默认值)。

希望对您有所帮助!

参考:AWS CloudSearch Documentation - Searching for Prefixes

我接受其他解决方案,但如果人们想看看 AWS SDK for PHP 的效果,我仍然会添加我真正做的事情:

1/ 我得到了用户搜索和 "clean" 搜索:

$_REQUEST['search'] = preg_replace(
    array('/\+/', '/-/', '/~/', '/>/', '/</', '/"/', '/\'/', '/\)/', '/\(/'), 
    "", 
    $_REQUEST['search']
);

2/ 然后我把每个词一个一个地爆搜索出来:

$word_list = explode(" ", trim($_REQUEST['search']));

3/ 现在我可以构建我的请求了:

// I start my query     
$event_query = "(and ";

// Now for each word, I add my condition :
// - I want each searched word in at least one of my 3 fields (nomevent, idftpevent and description)
// - I want the exact word or just a prefix
foreach ($word_list as $word) {
    $event_query .= "(or 
                       (prefix field=description '".$word."')
                       (prefix field=nomevent '".$word."')
                       (prefix field=idftpevent '".$word."')
                       (term field=description '".$word."')
                       (term field=nomevent '".$word."')
                       (term field=idftpevent '".$word."')
                     )";
}

// I close my query
$event_query .= ")";

4/ 现在我只需要使用 AWS SDK for PHP 来得到我的结果:

$search_result['event'] = $client->search(
    array(
        'query'        => $event_query,
        'queryParser'  => 'structured',
        'size'         => 500,
        'start'        => 0
    )
);

$search_result['event'] = $search_result['event']->toArray();

结果在 $search_result['event']['hits']['hit'] 中,也许有更好的方法来获得这些 hit 但这样我就实现了我想要的!