php中的Elasticsearch匹配子字符串
下面是我使用elasticsearch生成索引的代码。索引已成功生成。基本上,我使用它生成autosuggest,具体取决于电影名、演员名和gener 现在我的要求是,我需要将子字符串与特定字段相匹配。如果我使用php中的Elasticsearch匹配子字符串,php,
elasticsearch,elastica,Php,
elasticsearch,Elastica,下面是我使用elasticsearch生成索引的代码。索引已成功生成。基本上,我使用它生成autosuggest,具体取决于电影名、演员名和gener 现在我的要求是,我需要将子字符串与特定字段相匹配。如果我使用$params['body']['query']['wildcard']['field']='*sub_word*',这就可以了(即,搜索“to”会得到“tom kruz”,但搜索“tom kr”不会返回结果) 这只匹配字符串中的特定单词。我想匹配包含多个单词的子字符串(即“tom kr
$params['body']['query']['wildcard']['field']='*sub_word*',这就可以了代码>(即,搜索“to”会得到“tom kruz”,但搜索“tom kr”不会返回结果)
这只匹配字符串中的特定单词。我想匹配包含多个单词的子字符串(即“tom kr”应返回“tom kruz”)
我发现很少有文档说可以使用“ngram”。
但我不知道,我应该如何在代码中实现它,因为我正在为elasticsearch使用基于数组的配置,所有支持文档都提到json fromat中的配置
请帮忙
require 'vendor/autoload.php';
$client = \Elasticsearch\ClientBuilder::create()
->setHosts(['http://localhost:9200'])->build();
/*************Index a document****************/
$params = ['body' => []];
$j = 1;
for ($i = 1; $i <= 100; $i++) {
$params['body'][] = [
'index' => [
'_index' => 'pvrmod',
'_type' => 'movie',
'_id' => $i
]
];
if ($i % 10 == 0)
$j++;
$params['body'][] = [
'title' => 'salaman khaan'.$j,
'desc' => 'salaman khaan description'.$j,
'gener' => 'movie gener'.$j,
'language' => 'movie language'.$j,
'year' => 'movie year'.$j,
'actor' => 'movie actor'.$j,
];
// Every 10 documents stop and send the bulk request
if ($i % 10 == 0) {
$responses = $client->bulk($params);
// erase the old bulk request
$params = ['body' => []];
unset($responses);
}
}
// Send the last batch if it exists
if (!empty($params['body'])) {
$responses = $client->bulk($params);
}
需要“vendor/autoload.php”;
$client=\Elasticsearch\ClientBuilder::create()
->setHosts(['http://localhost:9200']->build();
/*************为文件编制索引****************/
$params=['body'=>[];
$j=1;
对于($i=1;$i)[
“_index”=>“pvrmod”,
“_type”=>“movie”,
“\u id”=>$i
]
];
如果($i%10==0)
$j++;
$params['body'][][
“title”=>“salaman khaan”。$j,
“描述”=>“salaman khaan描述”。$j,
“gener”=>“movie gener”。$j,
“语言”=>“电影语言”。$j,
“年”=>“电影年”。$j,
“演员”=>“电影演员”。$j,
];
//每10个文档停止并发送批量请求
如果($i%10==0){
$responses=$client->bulk($params);
//删除旧的批量请求
$params=['body'=>[];
未结算(答复);
}
}
//发送最后一批(如果存在)
如果(!empty($params['body'])){
$responses=$client->bulk($params);
}
尝试创建此JSON
{
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"wildcard": {
"field": {
"value": "tom*",
"boost": 1
}
}
},
{
"field": {
"brandname": {
"value": "kr*",
"boost": 1
}
}
},
]
}
}
}
}
你可以分解你的搜索词
$searchTerms = explode(' ', 'tom kruz');
然后为每一个创建通配符
foreach($searchTerms as $searchTerm) {
//create the new array
}
这里的问题在于Elasticsearch构建了一个倒排索引。假设您使用标准的分析器,句子“tom kruz是一个顶级高手”会被拆分为6个标记:tom-kruz-is-a-top-gun。这些标记会被分配到文档中(其中包含一些关于位置的元数据,但我们暂时不讨论)
如果要进行部分匹配,可以,但只能在单独的标记上,而不能像您希望的那样跨越标记边界。建议拆分搜索字符串并从这些字符串中构建通配符查询
另一种选择是使用or标记过滤器。这样做(在索引时)就是提前创建那些部分标记(如t-to-tom-…-k-kr-kru-kruz-…),您可以在(匹配)搜索中输入“tom-kr”,它就会匹配。不过要小心:这会使索引膨胀(如您所见,它将存储更多的令牌),您需要并且可能需要相当多的关于映射的知识
通常情况下,(边)ngram route是一个好主意,它只适用于自动完成之类的事情,而不仅仅适用于索引中的任何文本字段。有几种方法可以解决您的问题,但大多数都涉及到构建单独的功能来检测拼写错误的单词,并尝试为其提供正确的术语。亲爱的costa,谢谢您的回答。但您确定,只是一个查询,运行wildca吗对单个单词的rd搜索将提供与多单词子字符串匹配的最相关结果?