elasticsearch - 跨字段搜索,每个字段中有多个完整和不完整的短语

标签 elasticsearch

示例数据:

PUT /test/test/1
{
    "text1":"cats meow",
    "text2":"12345",
    "text3":"toy"
}

PUT /test/test/2
{
    "text1":"dog bark",
    "text2":"98765",
    "text3":"toy"
}

还有一个示例查询:
GET /test/test/_search
{
    "size": 25,
    "query": {
        "multi_match" : {
            "fields" : [
                "text1", 
                "text2",
                "text3"
            ],
            "query" : "meow cats toy",
            "type" : "cross_fields"
        }
    }
}

首先返回击中的猫,然后返回狗,这就是我想要的。

但查询cat toy时为,猫和狗的相关度得分相同。我希望能够考虑该单词的前缀(也许在该字段内还有其他几个单词),然后运行cross_fields

因此,如果我搜索:
GET /test/test/_search
{
    "size": 25,
    "query": {
        "multi_match" : {
            "fields" : [
                "text1", 
                "text2",
                "text3"
            ],
            "query" : "cat toy",
            "type" : "phrase_prefix"
        }
    }
}

要么
GET /test/test/_search
{
    "size": 25,
    "query": {
        "multi_match" : {
            "fields" : [
                "text1", 
                "text2",
                "text3"
            ],
            "query" : "meow cats",
            "type" : "phrase_prefix"
        }
    }
}

我应该得到cat / ID 1,但没有。

我发现使用cross_fields可以实现多个单词的短语,但不能实现多个不完整的短语。 phrase_prefix可以实现不完整的短语,但不能实现多个不完整的短语...

筛选documentation确实并没有帮助我发现如何结合这两者。

最佳答案

是的,我必须使用分析仪...

添加任何数据之前,在创建索引时将分析器应用于这些字段。添加数据后,我找不到更简单的方法来执行此操作。

我发现的解决方案是将所有短语分解成每个单独的前缀,以便cross_fields可以做到。您可以了解有关edge-ngram here的使用的更多信息。

因此,现在不再搜索cross_field短语,而不再搜索cats短语,而是现在要搜索:ccacatcats以及后面的每个短语...因此text1字段看起来像这样具有 flex :c ca cat cats m me meo meow

~~~

以下是使上述问题示例起作用的步骤:

首先,您创建并命名分析器。要了解更多有关过滤器值的含义,建议您看一下this

PUT /test
{
    "settings": {
        "number_of_shards": 1, 
        "analysis": {
            "filter": {
                "autocomplete_filter": { 
                    "type":     "edge_ngram",
                    "min_gram": 1,
                    "max_gram": 20
                }
            },
            "analyzer": {
                "autocomplete": {
                    "type":      "custom",
                    "tokenizer": "standard",
                    "filter": [
                        "lowercase",
                        "autocomplete_filter" 
                    ]
                }
            }
        }
    }
}

然后,我将此分析仪附加到每个字段。
我更改了text1以匹配我将其应用到的字段。
PUT /test/_mapping/test
{
    "test": {
        "properties": {
            "text1": {
                "type":     "string",
                "analyzer": "autocomplete"
            }
        }
    }
}

我运行GET /test/_mapping以确保一切正常。

然后添加数据:
POST /test/test/_bulk
{ "index": { "_id": 1 }}
{ "text1": "cats meow", "text2": "12345", "text3": "toy" }
{ "index": { "_id": 2 }}
{ "text1": "dog bark", "text2": "98765", "text3": "toy" }

和搜索!
{
    "size": 25,
    "query": {
        "multi_match" : {
            "fields" : [
                "text1", 
                "text2",
                "text3"
            ],
            "query" : "cat toy",
            "type" : "cross_fields"
        }
    }
}

哪个返回:
{
   "took": 3,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 2,
      "max_score": 0.70778143,
      "hits": [
         {
            "_index": "test",
            "_type": "test",
            "_id": "1",
            "_score": 0.70778143,
            "_source": {
               "text1": "cats meow",
               "text2": "12345",
               "text3": "toy"
            }
         },
         {
            "_index": "test",
            "_type": "test",
            "_id": "2",
            "_score": 0.1278426,
            "_source": {
               "text1": "dog bark",
               "text2": "98765",
               "text3": "toy"
            }
         }
      ]
   }
}

当您搜索cat toy时,这会在两者之间形成对比,而之前的分数是相同的。但是现在,cat命中具有应有的更高分数。这是通过考虑每个短语的每个前缀(在这种情况下/短语中最多20个字符),然后查看数据与cross_fields的相关性来实现的。

关于elasticsearch - 跨字段搜索,每个字段中有多个完整和不完整的短语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34777132/

相关文章:

python - 如何改进此功能以避免在 Elasticsearch 中索引重复文档

jquery - JSON 中的意外标记 {

用于对文档进行分类的 Elasticsearch 插件

elasticsearch - 从 ElasticSearch 索引中返回最近的记录

azure - 无法从服务器外部访问 ElasticSearch 实例 - Azure Windows 2012

elasticsearch - 将 elasticsearch 索引设置为只读是否有任何性能提升

elasticsearch - 搜索Elasticsearch时自定义分析器不起作用

elasticsearch - Elasticsearch 日期字段中的空字符串?

python - 像这样的Elasticsearch更像:相同的请求不同的响应

elasticsearch - 在elasticsearch上查找具有 bool 值的文档