Elasticsearch:将精确关键字与特殊字符匹配

时间:2017-07-28 20:20:08

标签: elasticsearch

我将标签存储为keywords

的数组
...
Tags: {
   type: "keyword"
},
...

产生如下数组:

Tags: [
    "windows",
    "opengl",
    "unicode",
    "c++",
    "c",
    "cross-platform",
    "makefile",
    "emacs"
]

我认为当我使用keyword类型时,我可以轻松地执行精确的搜索术语,因为它不应该使用任何分析器。

显然我错了!这给了我结果:

body.query.bool.must.push({term: {"_all": "c"}}); # 38 results

但这并不是:

body.query.bool.must.push({term: {"_all": "c++"}}); # 0 results

虽然显然存在此标记的实例,如上所示。

如果我改为使用body.query.bool.must.push({match: {"_all": search}});(使用match代替term),那么" c"和" c ++"返回完全相同的结果,这也是错误的。

1 个答案:

答案 0 :(得分:0)

这里的问题是您正在使用_all - Field,它使用分析器(默认为标准)。使用您的数据进行小测试以确保:

测试1:

curl -X POST http://127.0.0.1:9200/script/test/_search \
  -d '{
  "query": {
        "term" : { "_all": "c++"}
  }
}'

测试2:

curl -X POST http://127.0.0.1:9200/script/test/_search \
  -d '{
  "query": {
        "term" : { "tags": "c++"}
  }
}'

在我的测试中,第二个查询返回文档,首先不是。

您真的需要搜索多个字段吗?如果是这样,你可以覆盖_all字段的默认分析器 - 为了快速测试,我把一个索引设置为这样的设置:

{
    "settings": {
        "number_of_shards": 1,
        "number_of_replicas": 0
    },
    "mappings": {
        "test" : {
            "_all" : {"type" : "string", "index" : "not_analyzed", "analyzer" : "keyword"},
            "properties": {
                    "tags": {
                        "type": "keyword"
                    }
                }
        }
    }
}

或者您可以创建Custom _all Field

Multi Field query之类的解决方案,允许定义要搜索的字段列表,其行为与body.query.bool.must.push({match: {"_all": search}});的示例相似。