【问题标题】:Nested Should query(OR) inside a Must query(AND) in elastic Search弹性搜索中的必须查询(AND)内的嵌套应该查询(OR)
【发布时间】:2018-09-20 00:44:24
【问题描述】:

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

{
    "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: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) 在 endReadableNT (_stream_readable.js:1056:12) 在 _combinedTickCallback (内部/进程/next_tick.js:138:11) 在 process._tickCallback (internal/process/next_tick.js:180:9)"

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

【问题讨论】:

  • 为什么要使用 multi_match 查询?
  • 我是弹性搜索的新手,我正在尝试点击和试用以获得响应。我也可以使用query_string 没有问题。现在我在结合上述必须和嵌套的应该查询时遇到问题。
  • 那是因为你没有关闭must子句中的方括号
  • 不,在第二个中,您在 must 子句中打开方括号,并在 should 子句中关闭。如果第一个有效,为什么不尝试将所有内容都放在必须子句中?实际上,在 SQL 中翻译它时,您应该使用 AND 运算符编写
  • 您能否在此要点link 中更新并告诉我此查询有什么问题。

标签: javascript node.js elasticsearch


【解决方案1】:

这在 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"
            }
          ]
        }
      }
    ]
  }

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2021-09-01
      • 2015-09-24
      • 2020-07-26
      • 2017-06-11
      • 2014-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-28
      相关资源
      最近更新 更多