如何在多个字段的组合中执行“ALL”搜索?

时间:2017-08-22 18:27:41

标签: elasticsearch

说我有一个看起来像这样的文件:

{
  "title": "Dilemma: What's for lunch?",
  "description": "The age old question of what's for lunch has surfaced again."
  "tags": [
    { "title": "important" },
    { "title": "decision" }
  }
}

我希望在搜索dilemma AND question AND decision时返回此文档(请注意,搜索条件及其中存在的字段在此示例中是互斥的。)如果任何提供的条款不存在于任何字段,不应返回此文档(因此,如果我搜索dilemma AND question AND decision AND foobar,则不会返回任何内容。)

我尝试将bool个问题与mustshould以及match条款与operator: and的各种组合一起使用,但到目前为止还没有任何工作

我的问题是:这可以在查询时完成吗?或者我是否需要在索引时将titledescriptiontags.title合并到一个新字段(例如keywords)中(如果是,如何?)

1 个答案:

答案 0 :(得分:1)

查询本身可以从它的描述生成:你需要找到一个满足每个术语匹配的文档,其中匹配被视为titledescriptiontags.title包含术语。因此,对于每个术语,您只需要一个包含三个should子句的bool查询(每个字段一个),嵌套为must bool子句下的子查询之一:

{
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "should": [
              {
                "term": {
                  "title": "important"
                }
              },
              {
                "term": {
                  "description": "important"
                }
              },
              {
                "term": {
                  "tags.title": "important"
                }
              }
            ]
          }
        },
      ]
    }
  }
}

此查询只包含一个术语(因为它对于易于理解而言太大了),但扩展就像在must数组下添加新的bool查询一样简单。另请注意,您可能希望用不太严格的内容替换term查询。

这是我用于查询生成的ruby代码:

require 'json'

terms = %w[important dilemma decision]

clauses = terms.map do |term|
  {
    bool: {
      should: %w[title description tags.title].map do |field|
        {
          term: {
            field => term
          }
        }
      end
    }
  }
end

query = {
  query: {
    bool: {
      must: clauses
    }
  }
}

puts JSON.pretty_generate(query)