Elasticsearch匹配给定数组中的所有标记

时间:2016-07-05 16:34:56

标签: json node.js search elasticsearch

目前正在使用elasticsearch开发标签搜索应用程序,我已在索引中为每个文档提供了一系列标记,这里是文档外观的一个示例:

_source: {
  title: "Keep in touch scheme",
  intro: "<p>hello this is a test</p> ",
  full: " <p>again this is a test mate</p>",
  media: "",
  link: "/training/keep-in-touch",
  tags: [
    "employee",
    "training"
  ]
}

我希望能够进行搜索,只返回包含所有指定标签的文档。

使用上面的示例,如果我搜索带有标签["employee", "training"]的文档,则会返回上述结果。

相反,如果我使用标签["employee", "other"]进行搜索,则不会返回任何内容;搜索查询中的所有标记都必须匹配。

目前我在做:

query: {
  bool: {
    must: [
      { match: { tags: ["employee","training"] }}
     ]
   }
 }

但我刚刚收到像

这样的返回异常
IllegalStateException[Can't get text on a START_ARRAY at 1:128];

我还尝试连接数组并使用逗号分隔的字符串,但是这似乎与第一个标记匹配时的任何内容相匹配。

有关如何处理此问题的任何建议?干杯

2 个答案:

答案 0 :(得分:1)

选项1:下一个示例应该有效(v2.3.2):

curl -XPOST 'localhost:9200/yourIndex/yourType/_search?pretty' -d '{
  "query": {
    "bool": {
      "must": [
        { "term": { "tags": "employee" } } ,
        { "term": { "tags": "training" } }
      ]
    }
  }
}'

选项2:您也可以尝试:

curl -XPOST 'localhost:9200/yourIndex/yourType/_search?pretty' -d '{
  "query": {
    "filtered": {
      "query": {"match_all": {}},
      "filter": {
        "terms": {
          "tags": ["employee", "training"]
        }
      }
    }
  }
}'

但如果没有"minimum_should_match": 1,那么它的工作效果就不准确了。 我还发现了"execution": "and",但它也不准确。

选项3:另外,您尝试使用query_string它完美无缺,但看起来有点复杂:

curl -XPOST 'localhost:9200/yourIndex/yourType/_search?pretty' -d '{
"query" : {
    "query_string": {
      "query": "(tags:employee AND tags:training)"
    }
  }
}'

也许这对你有帮助......

答案 1 :(得分:0)

要确保集合仅包含指定的值,请维护辅助字段以跟踪标记计数。然后,您可以像下面一样查询以获得所需的结果

"query":{
   "bool":{
        "must":[
             {"term": {"tags": "employee"}},
             {"term": {"tags": "training"}},
             {"term": {"tag_count": 2}}
        ]  
   }
}