elasticsearch 如何在弹性搜索或选项中使用术语聚合
假设我有以下数据:elasticsearch 如何在弹性搜索或选项中使用术语聚合,elasticsearch,filter,aggregation,facets,elasticsearch,Filter,Aggregation,Facets,假设我有以下数据: car1: { color: blue, brand: mercedes } car2: { color: blue, brand: toyota } car3 { color: red, brand: mercedes } car4: { color: red, brand: toyota } car5: { color: green,brand: toyota } “color”的聚合为我提供了{blue:2,red:2,green:1} “品牌”的聚合给了我{m
car1: { color: blue, brand: mercedes }
car2: { color: blue, brand: toyota }
car3 { color: red, brand: mercedes }
car4: { color: red, brand: toyota }
car5: { color: green,brand: toyota }
“color”的聚合为我提供了{blue:2,red:2,green:1}
“品牌”的聚合给了我{mercedes:2,toyota:3}
到目前为止还不错
如果我搜索“color=blue”并在过滤后进行聚合,我最终会得到:
聚合“color”为我提供了{blue:2}
//仅适用于蓝色汽车
聚合“品牌”给了我{mercedes:1,toyota:1}
//只适用于蓝色汽车
在我的搜索中,我可能会为每个属性选择多个方面,因此搜索“蓝色”或“红色”或“绿色”汽车会得到所有记录
因此,我希望在过滤相应属性之前获得每个聚合值,但在其他属性之后,这样我也可以看到其他数量
此处不适用使用后置过滤器(循环参考)
我真的必须触发多个查询(对于主查询和每个聚合)
或者我必须在后期筛选之前使用所有聚合,并在每个聚合中再次放置除相应筛选器之外的所有筛选器(筛选器聚合)
感谢您的帮助
[A]
无过滤器
Color:
( ) blue: 2
( ) red: 2
( ) green: 1
Brand:
( ) toyota: 3
( ) mercedes: 2
[B] 过滤器:颜色=蓝色
Color:
(x) blue: 2
Brand:
( ) toyota: 1
( ) mercedes: 1
Color:
(x) blue: 2
( ) red: 2
( ) green: 1
Brand:
( ) toyota: 1
( ) mercedes: 1
[C] 过滤器:颜色=蓝色
Color:
(x) blue: 2
Brand:
( ) toyota: 1
( ) mercedes: 1
Color:
(x) blue: 2
( ) red: 2
( ) green: 1
Brand:
( ) toyota: 1
( ) mercedes: 1
或者我必须在后期筛选之前使用所有聚合并放置所有
在每个聚合中再次筛选除相应的
(过滤器总成。)
这样做
或者我必须在后期筛选之前使用所有聚合并放置所有
在每个聚合中再次筛选除相应的
(过滤器总成。)
这样做 根据您希望使用的上述示例功能,下面是一些查询 例如B: 此查询将仅提供整个查询的聚合。第一次在页面加载上运行时,查询部分将没有任何术语,因此您将获得颜色和品牌的完整聚合列表。如果用户选择了蓝色方面,那么查询将只返回与该方面匹配的文档。这意味着从返回集生成的聚合将与示例B中的方面列表相匹配
POST /cars/car/_search
{
"query": {
"term": {
"color": {
"value": "blue"
}
}
},
"aggs" : {
"colors" : {
"terms" : { "field" : "color" }
},
"brands" : {
"terms" : { "field" : "brand" }
}
}
}
例C:
例如,我相信您的目标是所有潜在的方面都应该是可见的,即使在执行搜索之后也是如此。为此,您需要创建一个聚合,该聚合使用全局上下文来获取所有文档,而不仅仅是查询返回的文档。在本例中,所有搜索都将返回颜色和品牌方面的完整列表
POST /cars/car/_search
{
"query": {
"term": {
"color": {
"value": "blue"
}
}
},
"aggs" : {
"all_cars" : {
"global": {},
"aggs" : {
"colors" : {
"terms" : { "field" : "color" }
},
"brands" : {
"terms" : { "field" : "brand" }
}
}
}
}
}
如果您的目标是允许用户始终查看所有可用的方面,那么请确保您的查询根据用户选择的方面的数量和类型进行自我调整
更新:根据下面的评论,这将结合两个选项。您可以通过这种方式获得完整的未过滤聚合和过滤聚合。您必须根据用户的操作以编程方式决定在显示中使用哪个方面列表
POST /cars/car/_search
{
"query": {
"term": {
"color": {
"value": "blue"
}
}
},
"aggs" : {
"colors" : {
"terms" : { "field" : "color" }
},
"brands" : {
"terms" : { "field" : "brand" }
},
"all_cars" : {
"global": {},
"aggs" : {
"colors" : {
"terms" : { "field" : "color" }
},
"brands" : {
"terms" : { "field" : "brand" }
}
}
}
}
}
更新2:您还可以嵌套聚合,以便通过过滤器预先计算各个方面
POST /cars/car/_search
{
"aggs" : {
"colors" : {
"terms" : { "field" : "color" },
"aggs" : {
"brandsByColor" : {
"terms" : { "field" : "brand" }
}
}
},
"brands" : {
"terms" : { "field" : "brand" },
"aggs" : {
"colorsByBrand" : {
"terms" : { "field" : "color" }
}
}
}
}
}
根据您想要的上述示例功能中的哪一个,下面是一些查询 例如B: 此查询将仅提供整个查询的聚合。第一次在页面加载上运行时,查询部分将没有任何术语,因此您将获得颜色和品牌的完整聚合列表。如果用户选择了蓝色方面,那么查询将只返回与该方面匹配的文档。这意味着从返回集生成的聚合将与示例B中的方面列表相匹配
POST /cars/car/_search
{
"query": {
"term": {
"color": {
"value": "blue"
}
}
},
"aggs" : {
"colors" : {
"terms" : { "field" : "color" }
},
"brands" : {
"terms" : { "field" : "brand" }
}
}
}
例C:
例如,我相信您的目标是所有潜在的方面都应该是可见的,即使在执行搜索之后也是如此。为此,您需要创建一个聚合,该聚合使用全局上下文来获取所有文档,而不仅仅是查询返回的文档。在本例中,所有搜索都将返回颜色和品牌方面的完整列表
POST /cars/car/_search
{
"query": {
"term": {
"color": {
"value": "blue"
}
}
},
"aggs" : {
"all_cars" : {
"global": {},
"aggs" : {
"colors" : {
"terms" : { "field" : "color" }
},
"brands" : {
"terms" : { "field" : "brand" }
}
}
}
}
}
如果您的目标是允许用户始终查看所有可用的方面,那么请确保您的查询根据用户选择的方面的数量和类型进行自我调整
更新:根据下面的评论,这将结合两个选项。您可以通过这种方式获得完整的未过滤聚合和过滤聚合。您必须根据用户的操作以编程方式决定在显示中使用哪个方面列表
POST /cars/car/_search
{
"query": {
"term": {
"color": {
"value": "blue"
}
}
},
"aggs" : {
"colors" : {
"terms" : { "field" : "color" }
},
"brands" : {
"terms" : { "field" : "brand" }
},
"all_cars" : {
"global": {},
"aggs" : {
"colors" : {
"terms" : { "field" : "color" }
},
"brands" : {
"terms" : { "field" : "brand" }
}
}
}
}
}
更新2:您还可以嵌套聚合,以便通过过滤器预先计算各个方面
POST /cars/car/_search
{
"aggs" : {
"colors" : {
"terms" : { "field" : "color" },
"aggs" : {
"brandsByColor" : {
"terms" : { "field" : "brand" }
}
}
},
"brands" : {
"terms" : { "field" : "brand" },
"aggs" : {
"colorsByBrand" : {
"terms" : { "field" : "color" }
}
}
}
}
}
我也有同样的问题,并设法解决了它 要做到这一点,需要ElasticSearch 1.4,它是通过过滤器聚合和“postfilters”实现的。 在1.4之前,我使用过滤查询来获得正确的聚合计数,并试图通过“全局:{},过滤器:{}”聚合来实现这一点。就像上面的答案一样。问题是,全局{}聚合忽略了查询本身,如果您与筛选并行地进行全文搜索,那么它将无法工作 现在是1.4。您所要做的就是运行正常的未筛选查询并对其应用postfilters。对于聚合,您使用filter aggregations,即应用所有postfilters,但应用聚合的字段上的postfilters除外 因此,在您的示例中,颜色和品牌都有一个和后过滤器。在颜色聚合中,您将使用品牌过滤器,而在品牌聚合中,您将使用颜色过滤器 就我而言,我有公司id和主题过滤器。以前我会这样做,但它只适用于match_all查询
POST /cars/car/_search
{
"size": "20",
"from": "0",
"aggs": {
"company_id": {
"terms": {
"field": "company_id",
"size": 10
}
},
"global_company": {
"global": {},
"aggs": {
"company_id_3": {
"filter": {
"term": {
"subjects": "710"
}
},
"aggs": {
"company_id_2": {
"terms": {
"field": "company_id"
}
}
}
}
}
}
},
"sort": [
{
"_score": "desc"
}
],
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"and": [
{
"term": {
"company_id": "1215"
}
},
{
"term": {
"subjects": "710"
}
}
]
}
}
}
}
现在我这样做了,它适用于所有人:
POST /cars/car/_search
{
"size": "20",
"from": "0",
"aggs": {
"company_id": {
"terms": {
"field": "company_id",
"size": 10
}
},
"global_company": {
"global": {},
"aggs": {
"company_id_3": {
"filter": {
"term": {
"subjects": "710"
}
},
"aggs": {
"company_id_2": {
"terms": {
"field": "company_id"
}
}
}
}
}
}
},
"sort": [
{
"_score": "desc"
}
],
"query": {
"match_all": {}
},
"filter": {
"and": [
{
"term": {
"company_id": "1215"
}
},
{
"term": {
"subjects": "710"
}
}
]
}
}
您可以看到我如何仅在company_id_3聚合上应用其他筛选器。在这里,您可以用任何您喜欢的查询替换match_all查询,您仍然可以得到OR-l