ElasticSearch嵌套查询与过滤器

Car*_*ari 5 nested elasticsearch

好吧,对于你们这些超级棒的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
              }
            }
          ]
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

pic*_*ypg 17

这里有几个活动的部分:

  1. filter您使用的顶级是"后过滤器",用于处理聚合删除内容.它存在的方式相当令人讨厌,但它在0.90天内被弃用,它将在Elasticsearch 5.0中完全删除.

    通过将其置于过滤后的查询中,您很可能会获得更好的性能,更不用说它听起来无论如何都是您的目标.

    • 它的替代品更恰当地命名post_filter.
  2. 您的nested过滤器的术语没有使用该字段的完整路径,您应该这样做.

    {
      "term": {
        "user_id": 1
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    应该:

    {
      "term": {
        "participants.user_id": 1
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

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

  3. 假设你不希望status8,那么你这样做完全.

  4. 使用size0的聚集意味着你会得到一切回来.这适用于较小的数据集,但是对于较大的数据集而言这将是痛苦的.

把它们放在一起(顺序是无关紧要的,但是在查询部分之后放置聚合通常是一个好主意,因为它是如何执行的):

{
  "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
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

注意:我将"must_not"部分从数组更改为单个对象.始终使用数组语法没有任何问题,但我只是没有表明这两种格式都有效.当然,如果您使用多个项目,则必须使用数组语法.