ElasticSearch嵌套查询与过滤器

时间:2015-05-08 20:37:41

标签: elasticsearch nested

好的,对于你们这些超级棒的ElasticSearch专家来说,这个可能不会太难。我有这个嵌套查询,我希望嵌套查询在非嵌套字段(状态)上进行过滤。我不知道把过滤器放在哪里。我试过把它放在一个查询中(下面),但那并没有给我正确的结果。你能救我一下吗?

{
  "aggs": {
    "status": {
      "terms": {
        "field": "status",
        "size": 0
      }
    }
  },
  "filter": {
    "nested": {
      "path": "participants",
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "user_id": 1
              }
            },
            {
              "term": {
                "archived": false
              }
            },
            {
              "term": {
                "has_unread": true
              }
            }
          ]
        }
      }
    }
  },
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must_not": [
            {
              "term": {
                "status": 8
              }
            }
          ]
        }
      }
    }
  }
}

1 个答案:

答案 0 :(得分:16)

这里有几个活动的部分:

  1. The top-level filter that you are using is a "post filter",用于在聚合处理完毕后移除。它存在的方式相当令人讨厌,但它在0.90天内被弃用,它将在Elasticsearch 5.0中完全删除。

    通过将其置于已过滤的查询中,您很可能会获得更好的性能,更不用说它听起来像是您的目标。

    • 替换它的名称更为恰当post_filter
  2. 您的nested filter条款使用该字段的完整路径,您应该这样做。

    {
      "term": {
        "user_id": 1
      }
    }
    

    应该是:

    {
      "term": {
        "participants.user_id": 1
      }
    }
    

    其余的嵌套对象也是如此。

  3. 假设您不希望status成为8,那么您完全可以做到这一点。

  4. 在汇总中使用size 0意味着您将返回所有内容。这适用于较小的数据集,但是在较大的数据集上会很痛苦。

  5. 将所有内容放在一起(顺序无关紧要,但在查询部分之后放置通常是一个好主意,因为它是如何执行的):

    {
      "query": {
        "filtered": {
          "filter": {
            "bool": {
              "must" : {
                "nested" : {
                  "path" : "participants",
                  "filter": {
                    "bool": {
                      "must": [
                        {
                          "term": {
                            "participants.user_id": 1
                          }
                        },
                        {
                          "term": {
                            "participants.archived": false
                          }
                        },
                        {
                          "term": {
                            "participants.has_unread": true
                          }
                        }
                      ]
                    }
                  }
                }
              },
              "must_not": {
                "term": {
                  "status": 8
                }
              }
            }
          }
        }
      },
      "aggs": {
        "status": {
          "terms": {
            "field": "status",
            "size": 0
          }
        }
      }
    }
    

    注意:我更改了" must_not"从数组到单个对象的部分。 总是使用数组语法没有错,但我没有表明两种格式都有效。当然,如果您使用多个项目,则必须使用数组语法。