【问题标题】:Using named queries (matched_queries) for nested types in Elasticsearch?在 Elasticsearch 中对嵌套类型使用命名查询(matched_queries)?
【发布时间】:2019-12-11 18:36:45
【问题描述】:

使用命名查询,我可以获得matched_queries 的布尔表达式列表,例如:

(query1) AND (query2 OR query3 OR true)

这是一个使用命名查询来匹配顶级文档字段的示例:

DELETE test

PUT /test

PUT /test/_mapping/_doc 
{
    "properties": {
      "name": {
        "type": "text"
      },
      "type": {
        "type": "text"
      },
      "TAGS": {
        "type": "nested"
      }
    }

}

POST /test/_doc
{
  "name" : "doc1",
  "type": "msword",
  "TAGS" : [
    {
      "ID" : "tag1",
      "TYPE" : "BASIC"
    },
    {
      "ID" : "tag2",
      "TYPE" : "BASIC"
    },
    {
      "ID" : "tag3",
      "TYPE" : "BASIC"
    }
  ]
}

# (query1) AND (query2 or query3 or true)
GET /test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": {
              "query": "doc1",
              "_name": "query1"
            }
          }
        }
      ],
      "should": [
        {
          "match": {
            "type": {
              "query": "msword",
              "_name": "query2"
            }
          }
        },
        {
          "exists": {
            "field": "type",
            "_name": "query3"
          }
        }
      ]
    }
  }
}

上述查询在响应中正确返回了所有三个matched_queries

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.5753641,
    "hits" : [
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "TKNJ9G4BbvPS27u-ZYux",
        "_score" : 1.5753641,
        "_source" : {
          "name" : "doc1",
          "type" : "msword",
          "TAGS" : [
            {
              "ID" : "ds1",
              "TYPE" : "BASIC"
            },
            {
              "ID" : "wb1",
              "TYPE" : "BASIC"
            }
          ]
        },
        "matched_queries" : [
          "query1",
          "query2",
          "query3"
        ]
      }
    ]
  }
}

但是,我正在尝试运行类似的搜索:

(query1) AND (query2 OR query3 OR true)

这一次只在嵌套的 TAGS 对象而不是顶级文档字段上。

我尝试了以下查询,但问题是我需要为嵌套对象提供 inner_hits 对象才能在响应中获得 matched_queries,我只能将其添加到三个之一查询。

GET /test/_search
{
  "query": {
    "bool": {
      "must": {
        "nested": {
          "path": "TAGS",
          "query": {
            "match": {
              "TAGS.ID": {
                "query": "tag1",
                "_name": "tag1-query"
              }
            }
          },
          // "inner_hits" : {}
        }
      },
      "should": [
        {
          "nested": {
            "path": "TAGS",
            "query": {
              "match": {
                "TAGS.ID": {
                  "query": "tag2",
                  "_name": "tag2-query"
                }
              }
            },
            // "inner_hits" : {}
          }
        },
        {
          "nested": {
            "path": "TAGS",
            "query": {
              "match": {
                "TAGS.ID": {
                  "query": "tag3",
                  "_name": "tag3-query"
                }
              }
            },
            // "inner_hits" : {}
          }
        }
      ]
    }
  }
}

如果我添加多个“inner_hits”,Elasticsearch 会报错。我已经注释掉了上面可以添加它的地方,但每个地方都只会返回单个匹配的查询。

我希望我对此查询的回复:

 "matched_queries" : [
          "tag1-query",
          "tag2-query",
          "tag3-query"
        ]

非常感谢任何帮助,谢谢!

【问题讨论】:

  • 这是个好问题!

标签: elasticsearch


【解决方案1】:

一位同事为此提供了解决方案;将_named 参数移动到每个nested 部分的正下方:

GET /test/_search
{
  "query": {
    "bool": {
      "must": {
        "nested": {
          "_name": "tag1-query",
          "path": "TAGS",
          "query": {
            "match": {
              "TAGS.ID": {
                "query": "tag1"
              }
            }
          }
        }
      },
      "should": [
        {
          "nested": {
            "_name": "tag2-query",
            "path": "TAGS",
            "query": {
              "match": {
                "TAGS.ID": {
                  "query": "tag2"
                }
              }
            }
          }
        },
        {
          "nested": {
            "_name": "tag3-query",
            "path": "TAGS",
            "query": {
              "match": {
                "TAGS.ID": {
                  "query": "tag3"
                }
              }
            }
          }
        }
      ]
    }
  }
}

这会在matched_queries 响应中正确返回所有三个标签:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 2.9424875,
    "hits" : [
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "TaNy9G4BbvPS27u--oto",
        "_score" : 2.9424875,
        "_source" : {
          "name" : "doc1",
          "type" : "msword",
          "TAGS" : [
            {
              "ID" : "ds1",
              "TYPE" : "DATASOURCE"
            },
            {
              "ID" : "wb1",
              "TYPE" : "WORKBOOK"
            },
            {
              "ID" : "wb2",
              "TYPE" : "WORKBOOK"
            }
          ]
        },
        "matched_queries" : [
          "tag1-query",
          "tag2-query",
          "tag3-query"
        ]
      }
    ]
  }
}

【讨论】:

  • 这个解决方案太棒了!我遇到了同样的问题,这对我帮助很大!
猜你喜欢
  • 2015-12-15
  • 2015-05-31
  • 2015-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-04
  • 1970-01-01
相关资源
最近更新 更多