首页 > 解决方案 > 带有必须和应该的 Elasticsearch 术语查询

问题描述

在问题中,“slovenian”和“slovakian”和“german”字段必须有“street”字段,但“turkish”字段没有“street”字段。当我运行查询时,我还想要按此顺序包含“土耳其”字段数据的文档。但我不希望其他文档按此顺序具有“国家”字段。

下面是我的查询,如果我运行查询,我不会得到具有“土耳其语”字段的文档的值。当我在 must 中删除“street”时,我得到了具有“turkish”字段的文档的值,但我也得到了另一个没有“street”字段的文档。

{
        "sort": [
            {
                "index_number.numeric": {
                    "order": "asc"
                }
            }
        ],
        "query": {
            "bool": {
                "must": [
                    {
                        "term": {
                            "street": {
                                "value": street_val
                            }
                        }
                    },
                    {
                        "range": {
                            "@timestamp": {
                                "gte": gte,
                                "lt": lte
                            }
                        }
                    },
                    {
                        "bool": {
                            "should": [
                                {
                                    "match": {
                                        "nation": "slovenian"
                                    }
                                },
                                {
                                    "match": {
                                        "nation": "slovakian"
                                    }
                                },
                                {
                                    "match": {
                                        "nation": "german"
                                    }
                                },
                                {
                                    "match": {
                                        "nation": "turkish"
                                    }
                                }
                            ]
                        }
                    }

                ]
            }
        }
    }

例如,(测试用例) 我想获取“国家”是“斯洛文尼亚”或“斯洛伐克”或“德国”或“土耳其”,但“斯洛文尼亚”和“斯洛伐克”和“德国”必须有“street_field”,但是“土耳其语”没有“街道”字段。我的意思是如果“slovenian”或“slovakian”或“german”有“street”字段,则获取所有内容,并获取“turkish”,但“turkish”是否有“street”字段并不重要。并且不要取其他人。最后通过“index_number”对它们进行排序。

  ....
  ... "index_number": 30, "nation": "turkish" ...
  ... "index_number": 210, "nation": "slovenian", "street": "slovenia_street_name" ...
  ... "index_number": 13, "nation": "slovakian", "street": "slovakia_street_name" ...
  ... "index_number": 21, "nation": "italian", "street": "italia_street_name" ...
  ... "index_number": 51, "nation": "german", "street": "german_street_name" ...
  ... "index_number": 13, "nation": "syrian" ...
  ... "index_number": 52, "nation": "french" ...
  ...

运行查询后,我希望我的搜索结果类似于下面的预期结果。

...
doc => ... "index_number": 13, "nation": "slovakian", "street": "slovakia_street_name" ...
doc => ... "index_number": 30, "nation": "turkish" ...
doc => ... "index_number": 51, "nation": "german", "street": "german_street_name" ...
doc => ... "index_number": 210, "nation": "slovenian", "street": "slovenia_street_name" ...
...
      

我怎样才能做到这一点 ?有人可以举个例子吗?谢谢回答

标签: elasticsearch

解决方案


您可以使用布尔查询的组合来实现您的用例

{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "must": [
              {
                "bool": {
                  "should": [
                    {
                      "match": {
                        "nation": "slovenian"
                      }
                    },
                    {
                      "match": {
                        "nation": "slovakian"
                      }
                    },
                    {
                      "match": {
                        "nation": "german"
                      }
                    }
                  ]
                }
              },
              {
                "bool": {
                  "must": {
                    "exists": {
                      "field": "street"
                    }
                  }
                }
              }
            ]
          }
        },
        {
          "match": {
            "nation": "turkish"
          }
        }
      ]
    }
  },
  "sort": {
    "index_number": {
      "order": "asc"
    }
  }
}

使用相同的样本索引数据(如问题中提供的),搜索结果将是

"hits": [
      {
        "_index": "65804647",
        "_type": "_doc",
        "_id": "3",
        "_score": null,
        "_source": {
          "index_number": 13,
          "nation": "slovakian",
          "street": "slovakia_street_name"
        },
        "sort": [
          13
        ]
      },
      {
        "_index": "65804647",
        "_type": "_doc",
        "_id": "1",
        "_score": null,
        "_source": {
          "index_number": 30,
          "nation": "turkish"
        },
        "sort": [
          30
        ]
      },
      {
        "_index": "65804647",
        "_type": "_doc",
        "_id": "5",
        "_score": null,
        "_source": {
          "index_number": 51,
          "nation": "german",
          "street": "german_street_name"
        },
        "sort": [
          51
        ]
      },
      {
        "_index": "65804647",
        "_type": "_doc",
        "_id": "2",
        "_score": null,
        "_source": {
          "index_number": 210,
          "nation": "slovenian",
          "street": "slovenia_street_name"
        },
        "sort": [
          210
        ]
      }
    ]

推荐阅读