弹性搜索:字符串数组上的完全匹配查询

时间:2016-10-09 13:27:01

标签: elasticsearch

鉴于此文件:

{"name": "Perfect Sunny-Side Up Eggs","ingredientList": ["canola oil","eggs"]}

我如何在弹性搜索中构建一个查询,以便在给定查询字词"油蛋"的字符串数组上返回完全匹配,到目前为止这是我所拥有的,但它返回其他不相关的文档:

POST /recipes/recipe/_search
{
   "query": {
      "match": {
         "ingredientList": {
            "query": [
               "oil",
               "eggs"
            ],
            "operator": "and"
         }
      }
   }
}
例如,

返回此文档但它不包含" oil"。结果应该只包含"油"和"鸡蛋":

{"name": "Quick Baked French Toast","ingredientList": ["butter","cinnamon raisin bread","eggs"]}

2 个答案:

答案 0 :(得分:1)

您的查询将如下所示:

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "ingredientList": "oil"
          }
        },
        {
          "term": {
            "ingredientList": "eggs"
          }
        }
      ]
    }
  }
}

给我结果:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "ingredients",
      "_type" : "recipe",
      "_id" : "AVeprXFrNutW6yNguPqp",
      "_score" : 1.0,
      "_source" : {
        "name" : "Perfect Sunny-Side Up Eggs",
        "ingredientList" : [ "canola oil", "eggs" ]
      }
    } ]
  }
}

答案 1 :(得分:0)

弹性没有API精确匹配数组。但是可以使用两种方法来实现相同的目的:

  1. 使用多个必须块(不推荐)

  2. 使用terms set查询和 "query": { "bool": { "must": [ { "terms_set": { "ingredientList": { "terms": ingredients, "minimum_should_match_script": { "source": "Math.min(params.num_terms, {})".format(len(ingredients)) } } } }, { "script": { "script": { "inline": "doc['ingredientList'].length == params.list_length", "lang": "painless", "params": { "list_length": len(ingredients) } } } } ] } }

    if ($q->num_rows() > 0) {
      return $q->result();
    }