过滤器facet返回所有文档的计数而不是范围

时间:2014-04-06 19:21:41

标签: elasticsearch faceted-search facet nest

我使用Elasticsearch和Nest为特定时间范围内的文档创建查询以及执行一些过滤器方面。查询如下所示:

{
  "facets": {
    "notfound": {
      "query": {
        "term": {
          "statusCode": {
            "value": 404
          }
        }
      }
    }
  },
  "filter": {
    "bool": {
      "must": [
        {
          "range": {
            "time": {
              "from": "2014-04-05T05:25:37",
              "to": "2014-04-07T05:25:37"
            }
          }
        }
      ]
    }
  }
}

在特定情况下,搜索的总命中数为21个文档,这些文档适合Elasticsearch中该时间范围内的文档。但是"没有发现" facet返回38,它符合StatusDode值为404的ErrorDocuments总数。

据我了解文档,facet从搜索中收集数据。在这种情况下," notfound" facet永远不能返回高于21的计数。

我在这里做错了什么?

2 个答案:

答案 0 :(得分:4)

过滤器/查询/过滤_查询/构面过滤器之间存在明显差异,这很有用。

顶级过滤器

{
    filter: {}
}

这用作后置过滤器,这意味着它将在查询阶段结束后过滤结果。由于构面是查询阶段的一部分,因此过滤器不会影响面临的文档。过滤器不会改变分数,因此非常可缓存。

顶级查询

{
    query: {}
}

查询会影响文档的分数,因此比过滤器的可缓存性更低。查询在查询阶段运行,因此也会影响面临的文档。

已过滤的查询

{
    query: {
        filtered: {
           filter: {}
           query: {}
        }
    }
}

这允许您在查询阶段运行过滤器,利用它们更好的可缓存性,并让它们影响面临的文档。

构面过滤器

"facets" : {
    "<FACET NAME>" : {
        "<FACET TYPE>" : {
            ...
        },
        "facet_filter" : {
            "term" : { "user" : "kimchy"}
        }
    }
}

这允许您将过滤器应用于运行构面的文档。请记住,除非您还在构面上指定global:true,否则它将是queryphase / facetfilter的组合。

查询构面/过滤器构面

{
    "facets" : {
        "wow_facet" : {
            "query" : {
                "term" : { "tag" : "wow" }
            }
        }
    }
}

@thomasardal在这种情况下使用的是完全正常的,它是一个返回单个值的facet类型:查询命中计数。

您的Query Facet返回38而不是21的事实是因为您在时间范围内使用过滤器。

您可以通过在filtered_query阶段的query中执行过滤器或将facet filter(不是filter_facet)应用于query_facet来解决此问题,但因为过滤器的缓存效果更好了更好地使用facet过滤器内部过滤facet。

令人困惑的过滤器在搜索对象上使用.FacetFilter()指定了构面。我将在1.0中更改此内容以避免将来出现混淆。

可悲的是:NEST中的.FacetFilter().FacetQuery()不允许您像其他方面一样指定facet filter

var results = typedClient.Search<object>(s => s
    .FacetTerm(ft=>ft
        .OnField("myfield")
        .FacetFilter(f=>f.Term("filter_facet_on_this_field", "value"))
    )
);

答案 1 :(得分:0)

您在此处发出的问题是,您在查询中执行Filter Facet而不是正常方面(将遵循通过查询过滤器应用的限制)。在JSON中,问题是由于构面名"query""notfound"条目之间的"terms"。这告诉Elasticsearch将此作为单独的查询运行,并对此单独查询的结果进行分析,而不是使用日期范围过滤器的主查询。所以你的JSON应该如下所示:

 {
  "facets": {
    "notfound": {
      "term": {
        "statusCode": {
         "value": 404
        }
      }
    }
  },
  "filter": {
    "bool": {
      "must": [
        {
          "range": {
            "time": {
              "from": "2014-04-05T05:25:37",
              "to": "2014-04-07T05:25:37"
            }
          }
        }
      ]
    }
  }
}

由于我发现您也使用NEST进行了标记,因此在使用NEST进行的通话中,您可能在搜索请求中使用FacetFilter,将其切换为Facet以获得所需的结果。