Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
php中的Elasticsearch匹配子字符串_Php_<img Src="//i.stack.imgur.com/RUiNP.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">elasticsearch_Elastica - Fatal编程技术网 elasticsearch,elastica,Php,elasticsearch,Elastica" /> elasticsearch,elastica,Php,elasticsearch,Elastica" />

php中的Elasticsearch匹配子字符串

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

下面是我使用elasticsearch生成索引的代码。索引已成功生成。基本上,我使用它生成autosuggest,具体取决于电影名、演员名和gener

现在我的要求是,我需要将子字符串与特定字段相匹配。如果我使用
$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搜索将提供与多单词子字符串匹配的最相关结果?