【问题标题】:Model 'or TRUE' in Elasticsearch boolean query for nested type?嵌套类型的 Elasticsearch 布尔查询中的模型“或 TRUE”?
【发布时间】:2019-12-10 16:19:43
【问题描述】:

我正在尝试在 Elasticsearch 中构建以下查询:

(query1) AND (query2 OR query2 OR TRUE)

'OR true' 部分是否可以使用 elasticsearch,或者是否有另一种结构化查询的方式以给出相同的结果?

我有一组文档,比如说 10 个,所有匹配 tag1,这 10 个文档中的一些也将匹配 tag2 和 tag3,如果是这样,我使用命名查询来告诉我哪些文档匹配 tag2 和 tag3 (匹配 tag2 和 tag3 的文档是匹配 tag1 的文档的子集)。

但是,即使没有匹配 tag2 或 tag3,我仍然应该从匹配 tag1 的初始查询中获得结果。

GET /test/_search
{
  "query": {
    "nested": {
      "path": "TAGS",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "TAGS.ID": {
                  "query": "tag1",
                  "_name": "tag1-query"
                }
              }
            },
            {
              "bool": {
                "should": [
                  {
                    "match": {
                      "TAGS.ID": {
                        "query": "tag2",
                        "_name": "tag2-query"
                      }
                    }
                  },
                  {
                    "match": {
                      "TAGS.ID": {
                        "query": "tag3",
                        "_name": "tag3-query"
                      }
                    }
                  },
                  // OR true here?
                ]
              }
            }
          ]
        }
      },
      "inner_hits": {}
    }
  }
}

更新:基于@Val 的评论。这是我的完整测试:

PUT /test

PUT /test/_mapping/_doc 
{
    "properties": {
      "name": {
        "type": "text"
      },
      "TAGS": {
        "type": "nested"
      }
    }

}

POST /test/_doc
{
  "name" : "doc1",
  "TAGS" : [
    {
      "ID" : "tag1",
      "TYPE" : "BASIC"
    },
    {
      "ID" : "tag2",
      "TYPE" : "BASIC"
    }
  ]
}


# (tag1) and (tag2 or tag3 or true)
GET /test/_search
{
  "query": {
    "nested": {
      "path": "TAGS",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "TAGS.ID": {
                  "query": "tag1",
                  "_name": "tag1-query"
                }
              }
            }
          ],
          "should": [
            {
              "match": {
                "TAGS.ID": {
                  "query": "tag2",
                  "_name": "tag2-query"
                }
              }
            },
            {
              "match": {
                "TAGS.ID": {
                  "query": "tag3",
                  "_name": "tag3-query"
                }
              }
            }
          ]
        }
      },
      "inner_hits": {}
    }
  }
}

运行上述查询只会得到以下结果:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.6931472,
    "hits" : [
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "SaOs8G4BbvPS27u-IouS",
        "_score" : 0.6931472,
        "_source" : {
          "name" : "doc1",
          "TAGS" : [
            {
              "ID" : "tag1",
              "TYPE" : "BASIC"
            },
            {
              "ID" : "tag2",
              "TYPE" : "BASIC"
            }
          ]
        },
        "inner_hits" : {
          "TAGS" : {
            "hits" : {
              "total" : 1,
              "max_score" : 0.6931472,
              "hits" : [
                {
                  "_index" : "test",
                  "_type" : "_doc",
                  "_id" : "SaOs8G4BbvPS27u-IouS",
                  "_nested" : {
                    "field" : "TAGS",
                    "offset" : 0
                  },
                  "_score" : 0.6931472,
                  "_source" : {
                    "ID" : "tag1",
                    "TYPE" : "BASIC"
                  },
                  "matched_queries" : [
                    "tag1-query"
                  ]
                }
              ]
            }
          }
        }
      }
    ]
  }
}

matched_queries 数组只报告了 tag1-query 的匹配项,而我原本希望它包含 tag1-querytag2-query

【问题讨论】:

  • 在这种情况下,您不需要OR TRUE,因为无论如何您都会得到您所期望的;-) 您只需将bool/should 移出must 就可以了去。当使用must 时,should 子句仅对提升匹配的文档有用。试试看!
  • 感谢@Val,但如果我将匹配查询移出 bool/should,这不意味着它们在 bool/must 中,因此会与 tag1 查询进行 AND 运算吗?跨度>
  • 没有should 数组应该是must 数组的兄弟
  • 谢谢@Val,试过了,但仍然有问题,用完整的复制步骤更新了我的答案,如果你有时间看看? :-) 谢谢

标签: elasticsearch


【解决方案1】:

您需要两个嵌套查询,因为您要检查两个不同嵌套元素(它们是引擎盖下的两个不同嵌套文档)的约束。试试这个:

{
  "query": {
    "bool": {
      "must": {
        "nested": {
          "path": "TAGS",
          "query": {
            "match": {
              "TAGS.ID": {
                "query": "tag1",
                "_name": "tag1-query"
              }
            }
          }
        }
      },
      "should": [
        {
          "nested": {
            "path": "TAGS",
            "query": {
              "match": {
                "TAGS.ID": {
                  "query": "tag2",
                  "_name": "tag2-query"
                }
              }
            }
          }
        },
        {
          "nested": {
            "path": "TAGS",
            "query": {
              "match": {
                "TAGS.ID": {
                  "query": "tag3",
                  "_name": "tag3-query"
                }
              }
            }
          }
        }
      ]
    }
  }
}

【讨论】:

  • 谢谢@Val,问题是“inner_hits”:{} 现在,我只能将它添加到其中一个查询中,否则,它会抱怨,并且它只会包含查询的匹配查询它添加到。例如。如果我将它添加到 tag1 查询中,它正确包含“tag1-query”,同样,如果我将它添加到“tag2-query”,它正确包含“tag2-query”。当我尝试将它添加到最外层的查询时,它也会产生影响。
  • 我已将此标记为答案,因为这是我最初提出的问题(如何建模“OR TRUE”),并且我已经针对我遇到的嵌套类型问题提出了 stackoverflow.com/questions/59283035/… ,谢谢@Val
  • 酷,很高兴它有帮助!感谢您提出新问题!
猜你喜欢
  • 2018-04-28
  • 2015-12-15
  • 1970-01-01
  • 2020-04-04
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 2016-03-27
  • 2013-12-19
相关资源
最近更新 更多