ElasticSearch 相邻词用于多个嵌套字段的嵌套查询

ElasticSearch adjacent words for nested queries over multiple nested fields

为嵌套(或不嵌套)查询查找相邻词,解决方法如下(答案见):

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "metadata",
            "query": {
              "bool": {
                "must": [
                  {
                    "wildcard": {
                      "metadata.text": "*antonio*"
                    }
                  },
                  {
                    "wildcard": {
                      "metadata.text": "*banderas*"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

这工作正常。但是,假设有多个嵌套字段,其中以相同的方式搜索 *antonio* *banderas*,假设现在我们有这个映射:

{
    "mappings:": {
        "properties": {
            "text": {
                "type": "text"
            },
            "metadata": {
                "type": "nested",
                "properties": {
                    "text": {
                        "type": "text"
                    }
                }
            },
            "other_metadata": {
                "type": "nested",
                "properties": {
                    "text": {
                        "type": "text"
                    }
                }
            }
        }
    }
}

如果我想在嵌套字段metadataother_metadata中搜索相邻的词,我应该使用match还是should? 我想要一个匹配 至少一个模式元数据或 other_metadata 的结果,所以我想使用 should 并将 minimum_should_match 设置为查询的标记数(由 \s - space 字符分隔)以这种方式:

{
    "should": [{
            "nested": {
                "path": "metadata",
                "query": {
                    "bool": {
                        "must": {
                            "wildcard": {
                                "metadata.text": "*antonio*"
                            }
                        }
                    }
                },
                "ignore_unmapped": true
            }
        },
        {
            "nested": {
                "path": "metadata",
                "query": {
                    "bool": {
                        "must": {
                            "wildcard": {
                                "metadata.text": "*banderas*"
                            }
                        }
                    }
                },
                "ignore_unmapped": true
            }
        },
        {
            "nested": {
                "path": "other_metadata",
                "query": {
                    "bool": {
                        "must": {
                            "wildcard": {
                                "other_metadata.text": "*antonio*"
                            }
                        }
                    }
                },
                "ignore_unmapped": true
            }
        },
        {
            "nested": {
                "path": "other_metadata",
                "query": {
                    "bool": {
                        "must": {
                            "wildcard": {
                                "other_metadata.text": "*banderas*"
                            }
                        }
                    }
                },
                "ignore_unmapped": true
            }
        }
    ],
    "minimum_should_match": 2
}

这似乎可行,但我的疑问如下:此处的 minimum_should_match=2 条件将确保这四个条件中至少有两个匹配,但不会确保这两个匹配条件是 both 与同一模式相关(例如 metadata 表示 *antonio**banderas*。如果是这样,如何确保?可能使用 must?但是怎么办?

您可以像这样进行子查询:

bool => should => bool => filter/must/should

{
  "query": {
    "bool": {
      "minimum_should_match": 1,
      "should": [
        {
          "bool": {
            "must": [
              {
                "nested": {
                  "ignore_unmapped": true,
                  "path": "metadata",
                  "query": {
                    "bool": {
                      "must": {
                        "wildcard": {
                          "metadata.text": "*antonio*"
                        }
                      }
                    }
                  }
                }
              },
              {
                "nested": {
                  "ignore_unmapped": true,
                  "path": "metadata",
                  "query": {
                    "bool": {
                      "must": {
                        "wildcard": {
                          "metadata.text": "*banderas*"
                        }
                      }
                    }
                  }
                }
              }
            ]
          }
        },
        {
          "bool": {
            "must": [
              {
                "nested": {
                  "ignore_unmapped": true,
                  "path": "other_metadata",
                  "query": {
                    "bool": {
                      "must": {
                        "wildcard": {
                          "other_metadata.text": "*antonio*"
                        }
                      }
                    }
                  }
                }
              },
              {
                "nested": {
                  "ignore_unmapped": true,
                  "path": "other_metadata",
                  "query": {
                    "bool": {
                      "must": {
                        "wildcard": {
                          "other_metadata.text": "*banderas*"
                        }
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}