搜索多个索引时,inner_hits不适用于嵌套过滤器

时间:2018-03-15 08:49:34

标签: elasticsearch nest elasticsearch-net

Elasticsearch版本 版本:6.2.2

我正在尝试搜索两个都有嵌套对象的索引。为了简单起见,我将使用这个例子。在查询中我使用“inner_hits”属性。

PUT /sales
{
    "mappings": {
        "_doc" : {
            "properties" : {
                "tags" : { "type" : "keyword" },
                "comments" : { 
                    "type" : "nested",
                    "properties" : {
                        "username" : { "type" : "keyword" },
                        "comment" : { "type" : "text" }
                    }
                }
            }
        }
    }
}

PUT /sales/_doc/1?refresh
{
    "tags": ["car", "auto"],
    "comments": [
        {"username": "baddriver007", "comment": "This car could have better brakes"},
        {"username": "dr_who", "comment": "Where's the autopilot? Can't find it"},
        {"username": "ilovemotorbikes", "comment": "This car has two extra wheels"}
    ]
}

PUT /markets
{
    "mappings": {
        "_doc" : {
            "properties" : {
                "name" : { "type" : "keyword" },
                "products" : { 
                    "type" : "nested",
                    "properties" : {
                        "name" : { "type" : "keyword" },
                        "sku" : { "type" : "text" }
                    }
                }
            }
        }
    }
}

POST /sales,markets/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "should": [
              {
                "nested": {
                  "path": "comments",
                  "inner_hits": {

                  },
                  "ignore_unmapped": true,
                  "query": {
                    "match_all": {}
                  }
                }   
              }]
          }
        },
        {
          "bool": {
            "should": [
              {
                "nested": {
                  "path": "products",
                  "inner_hits": {

                  },
                  "ignore_unmapped": true,
                  "query": {
                    "match_all": {}
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

所以这个查询会出错

{
  "error": {
    "root_cause": [
      {
        "type": "illegal_state_exception",
        "reason": "[match_all] no mapping found for type [comments]"
      },
      {
        "type": "illegal_state_exception",
        "reason": "[match_all] no mapping found for type [products]"
      }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
      {
        "shard": 0,
        "index": "markets",
        "node": "-22psoQNRLa8_Y9GeHBXaw",
        "reason": {
          "type": "illegal_state_exception",
          "reason": "[match_all] no mapping found for type [comments]"
        }
      },
      {
        "shard": 0,
        "index": "sales",
        "node": "-22psoQNRLa8_Y9GeHBXaw",
        "reason": {
          "type": "illegal_state_exception",
          "reason": "[match_all] no mapping found for type [products]"
        }
      }
    ]
  },
  "status": 500
}

但是当我在每个“inner_hits”中添加“ignore_unmapped”:true时:{“ignore_unmapped”:true}一切正常。这在NEST .net库中没有实现。

在“inner_hits”中使用“ignore_unmapped”是否正确,因为我在文档中没有找到这个“inner_hits”属性? 在NEST还有其他解决方案可以做到这一点。

更新

我尝试使用运算符重载查询,我得到了

Func<SearchDescriptor<object>, ISearchRequest> search = s => s.Type<object>()
                .Index(Indices.Index("sales", "markets"))
                .AllTypes()
                .Explain(false)
                .Query(q => (q
                    .Nested(n => n
                                .IgnoreUnmapped(true)
                                .Path(Infer.Field<SaleDocument>(f => f.Comments))
                                .InnerHits(ih => ih
                                    .Size(1)
                                )
                                .Query(q1 => q1
                                    .MatchAll()
                                )
                    ) && +q.Terms(t => t
                        .Field("_index")
                        .Terms(new[] { "sales" })
                    )
                ) || (q
                    .Nested(n => n
                        .IgnoreUnmapped(true)
                        .Path(Infer.Field<MarketDocument>(f => f.Products))
                        .InnerHits(ih => ih
                            .Size(1)
                        )
                        .Query(q1 => q1
                            .MatchAll()
                        )
                    ) && +q.Terms(t => t
                            .Field("_index")
                            .Terms(new[] { "markets" })
                        )
                )
            );

此代码创建了查询

POST /sales,markets/_search
{
  "from": 0,
  "size": 10,
  "explain": false,
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "must": [
              {
                "nested": {
                  "query": {
                    "match_all": {}
                  },
                  "path": "comments",
                  "inner_hits": {
                    "size": 1
                  },
                  "ignore_unmapped": true
                }
              }
            ],
            "filter": [
              {
                "terms": {
                  "_index": [
                    "sales"
                  ]
                }
              }
            ]
          }
        },
        {
          "bool": {
            "must": [
              {
                "nested": {
                  "query": {
                    "match_all": {}
                  },
                  "path": "products",
                  "inner_hits": {
                    "size": 1
                  },
                  "ignore_unmapped": true
                }
              }
            ],
            "filter": [
              {
                "terms": {
                  "_index": [
                    "markets"
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  }
}

再次出现错误

{
  "error": {
    "root_cause": [
      {
        "type": "illegal_state_exception",
        "reason": "[match_all] no mapping found for type [comments]"
      },
      {
        "type": "illegal_state_exception",
        "reason": "[match_all] no mapping found for type [products]"
      }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
      {
        "shard": 0,
        "index": "markets",
        "node": "-22psoQNRLa8_Y9GeHBXaw",
        "reason": {
          "type": "illegal_state_exception",
          "reason": "[match_all] no mapping found for type [comments]"
        }
      },
      {
        "shard": 0,
        "index": "sales",
        "node": "-22psoQNRLa8_Y9GeHBXaw",
        "reason": {
          "type": "illegal_state_exception",
          "reason": "[match_all] no mapping found for type [products]"
        }
      }
    ]
  },
  "status": 500
}

2 个答案:

答案 0 :(得分:0)

正如你所说,NEST中似乎缺少inner_hits属性;我现在打开一个问题,将其添加到下一个版本中。

ignore_unmapped是在需要inner_hits时处理此问题的方法。如果您不需要inner_hits,则可以将每个嵌套查询与term元数据字段上的"_index"查询相结合,在每种情况下定位相应的索引名称,以便嵌套查询仅针对包含目标字段的索引运行。

答案 1 :(得分:0)

此问题已在两个地方修复,并将在NEST或ElasticSearch的某些未来版本中提供。

    通过在InnerHits中添加IgnoreUnmapped()方法,
  1. NEST .net库。 https://github.com/elastic/elasticsearch-net/issues/3132

  2. 通过ignore_unmapped中的嵌套查询inner_hits属性继承ignore_unmapped进行弹性搜索 https://github.com/elastic/elasticsearch/issues/29071