【问题标题】:Nested ElasticSearch query results in too many items嵌套的 ElasticSearch 查询导致项目过多
【发布时间】:2014-06-16 16:39:13
【问题描述】:

下面的嵌套 ElasticSearch 查询返回一些它不应该命中的结果。许多结果不包含请求的订单号,但仍然列出。我没有得到所有文档,所以查询肯定会在某种程度上减少结果集。

{
  "query": {
    "nested": {
      "path": "orders",
      "query": {
        "match": {
          "orderNumber": "242347"
        }
      }      
    }
  }
}

查询结果(截断):

{
  "took":0,
  "timed_out":false,
  "_shards": {
    "total":1,
    "successful":1,
    "failed":0
  },
  "hits": {
    "total":60,
    "max_score":9.656103,
    "hits":[
      {
        "_index": "index1",
        "_type":"documenttype1",
        "_id":"mUmudQrVSC6rn68ujDJ8iA",
        "_score":9.656103,
        "_source" : {
          "documentId": 12093894,
          "orders": [
          {
            "customerId": 129048669,
            "orderNumber": "242347", // <-- CORRECT HIT ON ORDER
          },
          {
            "customerId": 229405848,
            "orderNumber": "431962"
          }
          ]
        }
      },
      {
        "_index":"index1",
        "_type":"documenttype1",
        "_id":"9iO5QBCpT_6kmH3CoBTdWw",
        "_score":9.656103, 
        "_source" : {
          "documentId": 43390283,
          // <-- ORDER ISN'T HERE BUT THE DOCUMENT IS HIT NEVERTHELESS!
          "orders": [
          {
            "customerId": 229405848,
            "orderNumber": "431962"
          },
          {
            "customerId": 129408979,
            "orderNumber": "142701"
          }
          ]
        }
      }
      // Left out 58 more results most of which do not contain
      // the requested order number.
    ]
  }
}

如您所见,有一个不应该存在的命中(实际上,其中有很多),因为没有一个订单包含请求的订单号。

这是documenttype1的映射:

{
   "index1":{
      "properties":{
         "documentId":{
            "type":"integer"
         },
         "orders":{
            "type":"nested",
            "properties":{
               "customerId":{
                  "type":"integer"
               },
               "orderNumber":{
                  "type":"string",
                  "analyzer":"custom_internal_code"
               }
            }
         }
      }
   }
}

最后,这里是澄清custom_internal_code 分析器的设置,如上图所示:

{
   "index1":{
      "settings":{
         "index.analysis.analyzer.custom_internal_code.filter.1":"asciifolding",
         "index.analysis.analyzer.custom_internal_code.type":"custom",
         "index.analysis.analyzer.custom_internal_code.filter.0":"lowercase",
         "index.analysis.analyzer.custom_internal_code.tokenizer":"keyword",
      }
   }
}

【问题讨论】:

  • 我不知道这是否相关,但您应该将字段的完整路径放在查询中(即:orders.orderNumber)
  • @DeH:谢谢。我已经验证在查询中指定完整路径 (orders.orderNumber) 没有任何区别。
  • 您能否在您的问题中添加您在 ES 中提供的示例文档?我可能有一个解释。
  • 从文档中,您必须对查询中的引用字段使用完整路径。所以orderNumber应该变成orders.orderNumber

标签: elasticsearch


【解决方案1】:
【解决方案2】:

看来你应该使用 bool 查询而不是 match。

但是。如果你只想过滤你的记录,你应该使用嵌套过滤器而不是查询。它运行得更快,因为您不必计算分数。

http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-nested-filter.html

{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "nested": {
          "path": "orders",
          "filter": {
            "bool": {
              "must": [
                {
                  "term": {
                    "orderNumber": "242347"
                  }
                }
              ]
            }
          },
          "_cache": true
        }
      }
    }
  }
}

【讨论】:

  • 谢谢。我必须删除外部“过滤”节点才能使其工作。遗憾的是,结果与我的查询相同。
  • 感谢您建议使用过滤,这本身就是有用的信息。
  • I had to remove the outer "filtered" node to make it work。但它定义了将应用过滤器。当 filtered 节点出现时,ES 会显示什么信息?
  • 如果我把它留在里面,我会得到Parse Failure [No parser for element [filtered]]]。也许这与我将其发布到 _search 的事实有关?
  • 哦,是的。您应该将其全部包装在查询中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-08
  • 2018-10-17
  • 1970-01-01
相关资源
最近更新 更多