首页 > 解决方案 > 某些弹性字段 DSL 查询可搜索,有些则不可搜索

问题描述

我正在使用 Elastic Search 6.8.1 和动态映射。我现在在索引中有一个文档,并且正在测试对各个字段的搜索。我发帖http://localhost:9200/documents/_search并发送 DSL 查询

{
    "query": 
        {"bool":{"must":{"term":{"name": "item2"}}} }
}

我得到了我期望的文件:

{
    "took": 4,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 1,
        "max_score": 0.2876821,
        "hits": [
            {
                "_index": "documents",
                "_type": "document",
                "_id": "nRMOs5DZg",
                "_score": 0.2876821,
                "_source": {
                    "freeform": "DEF",
                    "name": "item2",
                    "url": "s3://mybucket/key",
                    "visible": true
                }
            }
        ]
    }
}

现在,我想确保我可以通过将查询更改为来搜索“自由格式”字段

{
    "query": 
        {"bool":{"must":{"term":{"freeform": "DEF"}}}   }
}

这导致没有命中,我不明白为什么。

[编辑] 这是动态映射

{
    "documents": {
        "aliases": {},
        "mappings": {
            "document": {
                "properties": {
                    "freeform": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "name": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "url": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "visible": {
                        "type": "boolean"
                    }
                }
            }
        },
        "settings": {
            "index": {
                "creation_date": "1564776393764",
                "number_of_shards": "5",
                "number_of_replicas": "1",
                "uuid": "2er2TF-ySEKgk6gd32K6Ig",
                "version": {
                    "created": "6080199"
                },
                "provided_name": "documents"
            }
        }
    }
}

标签: elasticsearch

解决方案


没有看到你的映射很难回答,但我的猜测是:

动态映射尝试猜测要分配给您的字段的数据类型;字符串字段的默认值为"text"data type,这意味着它们的值被分析并存储为规范化术语列表,这对于自由文本搜索很有用。该字符串"item2"恰好在此分析中保持不变,但"DEF"将被分析为"def".

由于您使用的是term查询,因此查询的术语不会经过相同的分析过程,因此您必须使用分析的术语进行查询才能匹配文档。

尝试搜索"def"而不是"DEF"检验这个假设。此外,查看为您的索引自动生成的映射,您将看到每个字段映射到的数据类型。

如果确实如此,您可以执行以下几项操作之一:

  • 如果您想要精确字符串匹配:将映射从 更改textkeyword(您可以使用Dynamic Templates控制动态映射);或者使用keyword自动为您创建的子字段进行搜索,freeform.raw而不是freeform.
  • 如果您想要“自由文本”匹配:使用match查询而不是term查询,以便输入和文档值都经过相同的分析(但请确保您了解分析和匹配查询的工作原理)。

推荐阅读