Elasticsearch在php中匹配子字符串

Din*_*are 9 php elasticsearch elastica

下面给出的是我使用elasticsearch.Index生成索引的代码成功生成.基本上我用它来生成autosuggest,具体取决于电影名称,演员姓名和gener.

现在我的要求是,我需要将子字符串与特定字段匹配.如果我使用它,这工作正常$params['body']['query']['wildcard']['field'] = '*sub_word*';.(即搜索'to'给'tom kruz'但搜索'tom kr'不返回结果).

这只匹配string中的特定单词.我想匹配包含多个单词的子串(即'tom kr'应该返回'tom kruz').

我找到了很少的文档,说使用' ngram ' 是可能的.但我不知道,我应该如何在我的代码中实现它,因为我使用基于数组的弹性搜索配置,所有支持文档都提到了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);
}
Run Code Online (Sandbox Code Playgroud)

Fra*_*ank 6

这里的问题在于Elasticsearch构建了倒排索引.假设你使用标准分析仪,句子"汤姆克鲁兹是一把顶级枪"得到的分为6个令牌:汤姆 - 克鲁兹 - 是 - 顶级枪.这些令牌被分配给文档(有关于那里位置的一些元数据,但是现在让我们把它放在一边).

如果你想进行部分匹配,你可以,但只能在单独的标记上,而不是像你想要的那样在标记的边界上.从这些字符串中拆分搜索字符串和构建通配符查询的建议是一种选择.

另一种选择确实是使用ngramedge_ngram标记过滤器.什么,会做(在索引时间)创造的完整标志(如T -到-汤姆- ...... - K - KR -克鲁- KRUZ - ...)提前,你可以只是把"汤姆KR"在你的(匹配)搜索中它会匹配.但请注意:这会使您的索引膨胀(如您所见,它将存储更多令牌),您需要自定义分析器以及可能对您的映射有相当多的了解.

通常,(edge_)ngram路由仅适用于自动完成等操作,不适用于索引中的任何文本字段.有几种方法可以解决您的问题,但大多数方法涉及构建单独的功能来检测拼写错误的单词并尝试为其建议正确的术语.


cos*_*sta 5

尝试创建这个 JSON

{
"query": {
    "filtered": {
        "query": {
            "bool": {
                "should": [
                    {
                        "wildcard": {
                            "field": {
                                "value": "tom*",
                                "boost": 1
                            }
                        }
                    },
                    {
                        "field": {
                            "brandname": {
                                "value": "kr*",
                                "boost": 1
                            }
                        }
                    },
                ]
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以展开搜索字词

$searchTerms = explode(' ', 'tom kruz');
Run Code Online (Sandbox Code Playgroud)

然后为每个创建通配符

foreach($searchTerms as $searchTerm) {
//create the new array
}
Run Code Online (Sandbox Code Playgroud)