要求Elasticsearch用双引号(“)括起来的高亮单词,而不是将其砍掉

时间:2019-07-15 08:59:32

标签: elasticsearch

Elasticsearch:v7.2
应用程序:PHP-Laravel v5.7

你好,美好的一天!

我正在开发一个类似于搜索引擎的Web应用程序,而用户将输入将被指定给变量$keywords的单词。然后,我使用此查询来搜索整个索引:

$params = [
    'index' => 'my_index',
    'type'  => 'my_type',
    'from'  => 0,
    'size'  => 10,
    'body'  => [
        "query" => [
            'bool' => [
                'must' => [
                    [
                        "query_string" => [
                            "fields" => ['title','content'],
                            "query" => $keywords
                        ]
                    ]
                ]
            ]
        ]
    ]
];

$articles = $client->search($params);

现在,与我之前的post一样,我能够计算我的$keywords在索引文档中出现的次数。

这是我的highlight查询,附加到上面的$params

"highlight" => [
    "fields" => [
        "content" => ["number_of_fragments" => 0],
        "title" => ["number_of_fragments" => 0]
    ]
    'require_field_match' => true
]

即使$keywords用双引号(“)引起来,highlighter仍然将$keywords切开/分隔,并且我已经用双引号指定了它们以严格遵循这些words

例如,我的$ keywords包含"Ayala Alabang",但是当我显示输出时,它像这样

Sample Output

$keywords是分开的,但是根据输出,它们彼此相邻。

我的查询是否还有其他调整或修订?我在一些论坛中找到了一些相关的帖子或问题,他们的最后答复是从2019年3月开始,任何建议都将对解决这一难题起到极大的帮助

1 个答案:

答案 0 :(得分:0)

经过几天的深入研究,我找到了一种方法来正确隔离文档中找到的关键字

STEP 1

在您的"explain" => true中应用$params

$params = [
            'index' = "myIndex",
            'type'  => "myType",
            'size'  => 50,
            'explain' => true,
            'query' => [
                'match_all' => [
                    //your elasticearch query here
                ]
            ]
]

第2步

然后在执行$client->search($params)代码之后获取结果:

$result = $client->search($params);

然后,您的$result中将包含一个长文字 EXPLANATION ,而您的keywords及其frequency将以文本格式显示。:

try displaying via dd($result['explanation'])

注意,这里的问题是_explanation数组键的内容中有很多嵌套数组,因此我们想出了一个递归函数来寻找{{1 }}及其keywords

第3步

您需要创建一个函数,该函数将获得字符串 IN BETWEEN 中的重复字符串或其他字符串:

frequency

第4步

然后创建递归函数:

public static function get_string_between($string, $start, $end){
    $string = ' ' . $string;
    $ini = strpos($string, $start);
    if ($ini == 0) return '';
    $ini += strlen($start);
    $len = strpos($string, $end, $ini) - $ini;
    return substr($string, $ini, $len);
}

最后

我能够提取所有public static function extract_kwds($expln,$kwds) { foreach($expln as $k=>$v) { if($k == 'description' && strpos(json_encode($v),'weight(')!==false) { if(isset($kwds[$this->get_string_between($v,':',')')])) { $kwds[$this->get_string_between($v,':',')')] += intVal($this->get_string_between($expln['details'][0]['description'],'score(freq=',')')); } else { $kwds[$this->get_string_between($v,':',')')] = intVal($this->get_string_between($expln['details'][0]['description'],'score(freq=',')')); } } if($k == 'details' && count($v) != 0) { foreach($v as $k2=>$v2) { $kwds = $this->extract_kwds($v2,$kwds); } } } return $kwds; } 及其keywords或这些frequency在文档中出现多少次。