代码之家  ›  专栏  ›  技术社区  ›  kgangadhar

在弹性搜索中,嵌套的Should查询(OR)在Must查询(AND)中

  •  7
  • kgangadhar  · 技术社区  · 7 年前

    我有以下格式的弹性搜索数据:

    {
        "is_cricketer": 1,
        "name": "Abraham",
        "cities": [
            { "name": "stellenbosch" },
            { "name": "Nelspruit" },
            { "name": "East London" }
        ]
    },
    {
        "is_cricketer": 1,
        "name": "Abraham",
        "cities": [
            { "name": "Rustenburg" },
            { "name": "Nelspruit" },
            { "name": "East London" }
        ]
    },
    {
        "is_cricketer": 0,
        "name": "deVilliers",
        "cities": [
            { "name": "Cape town" },
            { "name": "Nelspruit" },
            { "name": "East London" }
        ]
    }
    

    我需要查询弹性搜索以获取所有配置文件 is_cricketer = 1 以及字段上的OR查询 cities.name name 领域ie

    ( profile.is_cricketer == 1 && (profile.name == 'Abraham' || profile.cities[i].name == 'Nelspruit' ))
    

    使用或查询字段获取配置文件 城市。名称 名称 匹配查询字符串的字段如下所示,它按预期工作:

    "should": [
        {
            "nested": {
                "path": "cities",
                "query": {
                    "multi_match": {
                        "query": "Nelspruit",
                        "fields": [
                            "cities.name"
                        ]
                    }
                }
            }
        },
        {
            "multi_match": {
                "query": "Abraham",
                "fields": [
                    "name"
                ]
            }
        }
    ]
    

    以及必须查询以获取包含字段的所有配置文件 is\U板球运动员 = 1. 具体如下:

    {
        "must": {
            "match": {
                "is_cricketer": "1"
            }
        }
    }
    

    以上两个查询都运行良好,我正在尝试将这两个查询结合起来,如下所示:

    {
        "query": {
            "bool": {
                "must": {
                    "match": {
                        "is_cricketer": "1"
                    }
                },
                "should": [
                    {
                        "nested": {
                            "path": "cities",
                            "query": {
                                "multi_match": {
                                    "query": "Nelspruit",
                                    "fields": [
                                        "cities.name"
                                    ]
                                }
                            }
                        }
                    },
                    {
                        "multi_match": {
                            "query": "Abraham",
                            "fields": [
                                "name"
                            ]
                        }
                    }
                ]
            }
        }
    }
    

    它不会返回预期结果,而是返回所有配置文件 is_cricketer = 1 不过滤 名称 城市。名称

    我还试图包括 should 内部查询必须按以下方式进行查询:

    {
        "query": {
            "bool": {
                "must": [{
                    "match": {
                        "is_cricketer": "1"
                    }
                }, {
                    "should": [
                        {
                            "nested": {
                                "path": "cities",
                                "query": {
                                    "multi_match": {
                                        "query": "Nelspruit",
                                        "fields": [
                                            "cities.name"
                                        ]
                                    }
                                }
                            }
                        },
                        {
                            "multi_match": {
                                "query": "Abraham",
                                "fields": [
                                    "name"
                                ]
                            }
                        }
                    ]
                }]
            }
        }
    }
    

    但我在上面的查询中遇到以下错误:

    “错误:[正在分析\u异常][应该]查询格式错误,没有start\u对象 查询名称后,带{line=1&col=64} at respond(/GitRepo/project/node\u modules/elasticsearch/src/lib/transport.js:307:15) 在checkRespForFailure(/GitRepo/project/node\u modules/elasticsearch/src/lib/transport.js:266:7) 在HttpConnector上。(/GitRepo/project/node\u modules/elasticsearch/src/lib/connectors/http.js:159:7) 在IncomingMessage。绑定(/GitRepo/project/node\u modules/elasticsearch/node\u modules/lodash/dist/lodash.js:729:21) 在emitNone(events.js:111:20) 在IncomingMessage。发出(events.js:208:7) 在endReadableNT(\u stream\u readable.js:1056:12) 在\u combinedTickCallback(内部/流程/下一步\u勾选:138:11) at过程_tickCallback(内部/进程/下一步\u tick.js:180:9)”

    如何组合这两个查询以获得所需的结果。任何帮助都将不胜感激。

    2 回复  |  直到 7 年前
        1
  •  26
  •   Saket Gupta    5 年前

    如果您想在must中使用should查询,可以按以下方式使用

    {
      "query": {
        "bool": {
          "must": [
            {
              "bool": {
                "should": [
                  {
                    ... your query here
                  }
                ]
              }
            }
          ]
        }
      }
    }
    
        2
  •  6
  •   jhilden    7 年前

    这在ES 6.0上对我很有效。

    安装程序

    PUT test1
    {
      "mappings": {
        "type1": {
          "properties": {
            "cities": {
              "type": "nested" 
            }
          }
        }
      }
    }
    
    POST test1/type1
    {
        "is_cricketer": 1,
        "name": "Abraham",
        "cities": [
            { "name": "stellenbosch" },
            { "name": "Nelspruit" },
            { "name": "East London" }
        ]
    }
    
    POST test1/type1
    {
        "is_cricketer": 1,
        "name": "Abraham",
        "cities": [
            { "name": "Rustenburg" },
            { "name": "Nelspruit" },
            { "name": "East London" }
        ]
    }
    
    POST test1/type1
    {
        "is_cricketer": 0,
        "name": "deVilliers",
        "cities": [
            { "name": "Cape town" },
            { "name": "Nelspruit" },
            { "name": "East London" }
        ]
    }
    

    查询

    GET test1/type1/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "is_cricketer": {
                  "value": 1
                }
              }
            }
          ],
          "should": [
            {
              "term": {
                "name.keyword": {
                  "value": "Abraham"
                }
              }
            },
            {
              "nested": {
                "path": "cities",
                "query": {
                  "term": {
                    "cities.name.keyword": {
                      "value": "Nelspruit"
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
    

    结果-2次点击

     "hits": {
        "total": 2,
        "max_score": 2.2685113,
        "hits": [
          {
            "_index": "test1",
            "_type": "type1",
            "_id": "zgcesWIBVwCaLf8KSuDi",
            "_score": 2.2685113,
            "_source": {
              "is_cricketer": 1,
              "name": "Abraham",
              "cities": [
                {
                  "name": "stellenbosch"
                },
                {
                  "name": "Nelspruit"
                },
                {
                  "name": "East London"
                }
              ]
            }
          },
          {
            "_index": "test1",
            "_type": "type1",
            "_id": "eAQesWIBbxh35CpKckEH",
            "_score": 2.2685113,
            "_source": {
              "is_cricketer": 1,
              "name": "Abraham",
              "cities": [
                {
                  "name": "Rustenburg"
                },
                {
                  "name": "Nelspruit"
                },
                {
                  "name": "East London"
                }
              ]
            }
          }
        ]
      }