针对elasticsearch中的多个值查询嵌套对象属性

时间:2015-05-06 20:59:07

标签: elasticsearch

让我们说我们有两个属性标签和组的嵌套对象注释。如果我在下面查询,那么它会给我所需的结果。



{
  "query": {
    "bool": {
      "must": {
        "nested": {
          "query": {
            "bool": {
              "must": {
                "match": {
                  "comment.tag": {
                    "query": "SPRING",
                    "type": "boolean"
                  }
                }
              },
              "must_not": {
                "match": {
                  "comment.group": {
                    "query": "ABC",
                    "type": "boolean"
                  }
                }
              }
            }
          },
          "path": "comment"
        }
      }
    }
  }
}




但如果我执行以下查询,那么它并没有给我所需的结果。



{
  "query": {
    "bool": {
      "must": {
        "nested": {
          "query": {
            "bool": {
              "must": {
                "match": {
                  "comment.tag": {
                    "query": [
                      "SPRING",
                      "HIBERNATE"
                    ],
                    "type": "boolean"
                  }
                }
              },
              "must_not": {
                "match": {
                  "comment.group": {
                    "query": [
                      "ABC",
                      "XYZ"
                    ],
                    "type": "boolean"
                  }
                }
              }
            }
          },
          "path": "comment"
        }
      }
    }
  }
}




这两者之间的区别在于我正在针对多个值查询嵌套对象的两个属性。

使用第二个查询,它只会获取提供给搜索的列表中的最后一个值并返回结果。

有没有办法编写查询,我可以指定值的传递列表,所有值都包含在搜索中?

1 个答案:

答案 0 :(得分:2)

这与嵌套查询/过滤器无关。相反,它是你如何使用match query。它不期望一组值。

实际上有两种方法可以实现您的尝试。在进入它们之前,我确实想要注意match查询默认使用boolean类型,因此您可以将其保留。

  1. 您可以更改match查询以简单地在字符串中提供这两个值。订单无关紧要:

    "bool" : {
      "must" : {
        "match" : {
          "comment.tag" : "SPRING HIBERNATE"
        }
      }
    }
    

    这样做的原因是因为该字段将使用搜索分析器以与索引字段相同的方式标记字符串(默认情况下)。因此,假设使用默认字符串分析器,您最终将搜索spring hibernate。因为您没有使用词组匹配,所以订单确实无关紧要。

  2. 另一种方法是使用外部bool / must查询明确区分它们(同样适用于must_notshould)。由于您希望将它们视为OR s,因此您需要使用should代替must

    "bool" : {
      "should" : [
        {
          "match" : { "company.tag" : "SPRING" }
        },
        {
          "match" : { "company.tag" : "HIBERNATE" }
        }
      ]
    }
    

    注意:如果还包含must,则需要将minimum_should_match设置为1(在bool对象内),这样它才不会成为可选项。如果没有mustmust_not,则隐含为1。