Elasticsearch-带部分词的匹配词匹配

时间:2019-10-04 10:49:37

标签: php elasticsearch search

我是Elasticsearch的新手,我无法在结果上得到想要的分数。

这是我到目前为止获得的最佳工作选择。

$options['query']['bool']['should'][] = [
    'match' => [
        'my_long_textfield' => [
            'query' => $query,
            'operator' => 'AND',
            'boost' => 15
        ]
    ]
];

$options['query']['bool']['should'][] = [
    'match' => [
        'my_long_textfield' => [
            'query' => $query,
            'minimum_should_match' => '80%'
        ]
    ]
];

示例数据集(两行):

my_long_textfield:
"some cars move fast"
"a car can move quickly"

如果我的查询是“汽车快速”,它将给第二行最高分,因为第一行包含“汽车”而不是“汽车”。

我想给单词匹配以及部分单词打分。

因此,对于查询“ car fast”,我们在单词“ fast”上有一个匹配项,而“ car”在第一行中几乎是一个单词匹配项。而且得分应该更高,然后第二行只有一个单词匹配。

如果有人能指出我正确的方向,将不胜感激。

1 个答案:

答案 0 :(得分:1)

有很多方法可以解决此问题,但是最简单的方法是利用分析器。在您的情况下,您可以将my_long_textfield配置为使用english language analyzer,除了删除停用词外,它也可以词干(例如car的索引cars),即您需要什么(在进入模糊状态之前)。

因此,首先使用适合该字段的分析器创建索引:

PUT test
{
  "mappings": {
    "properties": {
      "my_long_textfield": {
        "type": "text",
        "analyzer": "english"
      }
    }
  }
}

然后索引两个测试文档:

POST test/_doc/_bulk
{ "index": {}}
{ "my_long_textfield": "some cars move fast" }
{ "index": {}}
{ "my_long_textfield": "a car can move quickly" }

然后,您的查询将为您提供准确的期望,即第一个文档的得分高于第二个文档的得分:

POST test/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "my_long_textfield": {
              "query": "car fast",
              "operator": "AND",
              "boost": 15
            }
          }
        },
        {
          "match": {
            "my_long_textfield": {
              "query": "car fast",
              "minimum_should_match": "80%"
            }
          }
        }
      ]
    }
  }
}

结果=>

"hits" : [
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "w3uIlm0B0Vd4Dh649_Vg",
    "_score" : 14.0075,
    "_source" : {
      "my_long_textfield" : "some cars move fast"
    }
  },
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "xHuIlm0B0Vd4Dh649_Vg",
    "_score" : 0.18232156,
    "_source" : {
      "my_long_textfield" : "a car can move quickly"
    }
  }
]

如果您再考虑一点,我们也可以添加一个synonym token filter,因为fastquick的意思是相同的,但这是另一回事。