嵌套应该在弹性搜索中的必需查询(AND)内查询(OR)

时间:2018-04-10 11:50:56

标签: javascript node.js elasticsearch

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

{
    "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的所有个人资料以及cities.namename字段的字段的OR查询。即

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

要在字段cities.namename字段中获取带有OR查询的配置文件,以便匹配查询字符串,如下所示,它可以正常工作:

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

使用字段is_cricketer = 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,未过滤namecities.name

我还尝试将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"
                            ]
                        }
                    }
                ]
            }]
        }
    }
}

但是我在上述查询中遇到以下错误:

  

“错误:[parsing_exception] [应该]查询格式错误,没有start_object   查询名称之后,{line = 1& col = 64}       在回应时(/GitRepo/project/node_modules/elasticsearch/src/lib/transport.js:30:15)       at checkRespForFailure(/GitRepo/project/node_modules/elasticsearch/src/lib/transport.js:266:7)       在HttpConnector。 (/GitRepo/project/node_modules/elasticsearch/src/lib/connectors/http.js:159:7)       在IncomingMessage.bound(/GitRepo/project/node_modules/elasticsearch/node_modules/lodash/dist/lodash.js:729:21)       在emitNone(events.js:111:20)       在IncomingMessage.emit(events.js:208:7)       at endReadableNT(_stream_readable.js:1056:12)       at _combinedTickCallback(internal / process / next_tick.js:138:11)       at process._tickCallback(internal / process / next_tick.js:180:9)“

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

2 个答案:

答案 0 :(得分:10)

如果您想在must内部查询应查询,则可以按以下方式使用

{
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "should": [
              {
                ... your query here
              }
            ]
          }
        }
      ]
    }
  }
}

答案 1 :(得分:2)

这适用于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"
            }
          ]
        }
      }
    ]
  }