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

kga*_*har 4 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" }
    ]
}
Run Code Online (Sandbox Code Playgroud)

我需要查询弹性搜索以获取所有带有is_cricketer=的配置文件1以及对字段cities.namename字段的 OR 查询。IE

( profile.is_cricketer == 1 && (profile.name == 'Abraham' || profile.cities[i].name == 'Nelspruit' ))
Run Code Online (Sandbox Code Playgroud)

在字段cities.namename字段上使用 OR 查询获取配置文件以匹配查询字符串如下,它按预期工作:

"should": [
    {
        "nested": {
            "path": "cities",
            "query": {
                "multi_match": {
                    "query": "Nelspruit",
                    "fields": [
                        "cities.name"
                    ]
                }
            }
        }
    },
    {
        "multi_match": {
            "query": "Abraham",
            "fields": [
                "name"
            ]
        }
    }
]
Run Code Online (Sandbox Code Playgroud)

获取带有字段is_cricketer= 的所有配置文件的 Must 查询1如下:

{
    "must": {
        "match": {
            "is_cricketer": "1"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以上两个查询工作正常,我正在尝试按如下方式组合两个查询:

{
    "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"
                        ]
                    }
                }
            ]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它没有返回预期的结果,它返回所有配置文件, is_cricketer = 1而没有过滤namecities.name

我还尝试将should查询包含在 must 查询中,如下所示:

{
    "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"
                            ]
                        }
                    }
                ]
            }]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

“错误:[parsing_exception] [应该] 查询格式错误,查询名称后没有 start_object,响应时为 { line=1 & col=64 } (/GitRepo/project/node_modules/elasticsearch/src/lib/transport.js:307: 15) 在 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)"

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

小智 17

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

{
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "should": [
              {
                ... your query here
              }
            ]
          }
        }
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


jhi*_*den 5

这在 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" }
    ]
}
Run Code Online (Sandbox Code Playgroud)

询问

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"
                }
              }
            }
          }
        }
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

结果 - 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"
            }
          ]
        }
      }
    ]
  }
Run Code Online (Sandbox Code Playgroud)