ElasticSearch中的AND&OR查询

fdx2calv  于 2022-10-06  发布在  ElasticSearch
关注(0)|答案(2)|浏览(166)

我是Elastic Search的新手,我有如下文档:

相同JSON索引的Map如下:

Map

{
      "mappings": {
        "properties": {
          "age": {
            "type": "long"
          },
          "hobbiles": {
            "type": "keyword"
          }

      }
    }
}

一些示例文档如下所示:

[{
        "_id": "test@domain.com",
        "age": 12,
        "hobbiles": [{
                "name": "Singing",
                "level": "begineer"
            },
            {
                "name": "Dancing",
                "level": "begineer"
            }
        ]
    },
    {
        "_id": "test1@domain.com",
        "age": 7,
        "hobbiles": [{
                "name": "Coding",
                "level": "begineer"
            },
            {
                "name": "Chess",
                "level": "begineer"
            }
        ]
    },
    {
        "_id": "test2@domain.com",
        "age": 20,
        "hobbiles": [{
                "name": "Singing",
                "level": "begineer"
            },
            {
                "name": "Dancing",
                "level": "begineer"
            }
        ]
    },
    {
        "_id": "test3@domain.com",
        "age": 21,
        "hobbiles": [{
                "name": "Coding",
                "level": "begineer"
            },
            {
                "name": "Dancing",
                "level": "Football"
            }
        ]
    }
]

现在我想获取id为in(test@domain.com,test1@domain.com)且年龄大于5的文档。[操作上]业余足球。

我对输出的期望是我应该得到三份文档:如果爱好不匹配,那么也应该很好,但如果爱好匹配,那么这份文档应该排在首位。基本上我想匹配爱好,但它是可选的,如果它不匹配,那么我也应该获得基于先前条款的数据。

[test3@domain.com, test@domain.com, test1@domain.com]

Test3在上面,因为Football在那里比赛,而Test1和Test1在那里,因为年龄和ID匹配。

gajydyqb

gajydyqb1#

这需要使用Should子句。“应该”相当于“或”。因此,如果文档满足应该查询中的任何一个条件,则将返回该文档。

对于ID和年龄的条件,我使用了Filter子句。它相当于“and”。FILTER子句不计算匹配文档的分数,因此匹配“hobbiles.Level”的任何文档的排名都会更高。

查询

{
  "query": {
    "bool": {
      "minimum_should_match": 1, 
      "should": [
        {
          "term": {
            "hobbiles.level.keyword": {
              "value": "Football"
            }
          }
        },
        {
          "bool": {
            "filter": [
              {
                "terms": {
                  "id.keyword": [
                    "test@domain.com",
                    "test1@domain.com"
                  ]
                }
              },
              {
                "range": {
                  "age": {
                    "gt": 5
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

结果

"hits" : [
      {
        "_index" : "index8",
        "_type" : "_doc",
        "_id" : "qE06noMBfFiM6spcUTo4",
        "_score" : 1.3112575,
        "_source" : {
          "id" : "test3@domain.com",
          "age" : 21,
          "hobbiles" : [
            {
              "name" : "Coding",
              "level" : "begineer"
            },
            {
              "name" : "Dancing",
              "level" : "Football"
            }
          ]
        }
      },
      {
        "_index" : "index8",
        "_type" : "_doc",
        "_id" : "pE03noMBfFiM6spc4jr2",
        "_score" : 0.0,
        "_source" : {
          "id" : "test@domain.com",
          "age" : 12,
          "hobbiles" : [
            {
              "name" : "Singing",
              "level" : "begineer"
            },
            {
              "name" : "Dancing",
              "level" : "begineer"
            }
          ]
        }
      },
      {
        "_index" : "index8",
        "_type" : "_doc",
        "_id" : "pU03noMBfFiM6spc6DqZ",
        "_score" : 0.0,
        "_source" : {
          "id" : "test1@domain.com",
          "age" : 7,
          "hobbiles" : [
            {
              "name" : "Coding",
              "level" : "begineer"
            },
            {
              "name" : "Chess",
              "level" : "begineer"
            }
          ]
        }
      }
    ]
vyu0f0g1

vyu0f0g12#

TLDR;

它可以通过布尔查询来实现。

解决方案

PUT /_bulk
{"index":{"_index":"73935795", "_id":"test@domain.com"}}
{"age":12,"hobbiles":[{"name":"Singing","level":"begineer"},{"name":"Dancing","level":"begineer"}]}
{"index":{"_index":"73935795", "_id":"test1@domain.com"}}
{"age":7,"hobbiles":[{"name":"Coding","level":"begineer"},{"name":"Chess","level":"begineer"}]}
{"index":{"_index":"73935795", "_id":"test2@domain.com"}}
{"age":20,"hobbiles":[{"name":"Singing","level":"begineer"},{"name":"Dancing","level":"begineer"}]}
{"index":{"_index":"73935795", "_id":"test3@domain.com"}}
{"age":21,"hobbiles":[{"name":"Coding","level":"begineer"},{"name":"Dancing","level":"Football"}]}

GET 73935795/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "age": {
              "gt": 5
            }
          }
        },
        {
          "terms": {
            "_id": [
              "test@domain.com",
              "test1@domain.com",
              "test3@domain.com"
            ]
          }
        }
      ],
      "should": [
        {
          "query_string": {
            "query": "(football) OR (begineer)",
            "default_field": "hobbiles.level"
          }
        }
      ]
    }
  }
}

相关问题