过滤器中的聚合只返回所有过滤文档中存在的值?
Aggregations in a filter only returning values if present in all filtered documents?
对于电子商务过滤系统,必须在整个过滤集上计算 ElasticSearch 中的聚合。
没有过滤器,我们得到:
"filters":{
"colour":{
"red":{
"count":5
},
"blue":{
"count":4
}
},
"size":{
"L":{
"count":16
},
"M":{
"count":15
}
}
}
仅过滤红色,我们得到:
"filters":{
"colour":{
"red":{
"count":5
},
"blue":{
"count":3
}
},
"size":{
"L":{
"count":1
},
"M":{
"count":1
}
}
}
只过滤蓝色,我们得到:
"filters":{
"colour":{
"blue":{
"count":4
},
"red":{
"count":3
}
}
}
蓝色没有尺码,没关系。但是,如果我们将两者结合起来:
"filters":{
"colour":{
"red":{
"count":5
},
"blue":{
"count":4
}
},
"size":{
"L":{
"count":1
},
"M":{
"count":1
}
根本不应返回尺码,因为它与两种颜色都不匹配。
这是发送给 ES 的内容:
{
"size":1000,
"fields":[
"id",
"name",
"price",
"colour",
"size"
],
"query":{
"filtered":{
"query":{
"match_all":{}
},
"filter":{
"bool":{
"must":[
{
"term":{
"categories":4838
}
},
{
"bool":{
"should":[
{
"term":{
"colour":"blue"
}
},
{
"term":{
"colour":"red"
}
}
]
}
}
]
}
}
}
},
"aggs":{
"price":{
"stats":{
"field":"price"
}
},
"discounted":{
"terms":{
"field":"discounted"
}
},
"stock":{
"filter":{
"range":{
"stock":{
"gt":0
}
}
}
},
"colour":{
"terms":{
"field":"colour"
}
},
"size":{
"terms":{
"field":"size"
}
}
}
}
出了什么问题?如何设置仅在匹配所有文档的过滤子集上聚合?
结果与查询一致
{
"bool": {
"must": [{
"term": {
"categories": 4838
}
}, {
"bool": {
"should": [{
"term": {
"colour": "blue"
}
}, {
"term": {
"colour": "red"
}
}]
}
}]
}
}
您要的是蓝色 或 红色的类别 4838 的商品。当您对大小执行聚合时,会为数据集中的每个大小创建存储桶,其中包含类别 4838 的蓝色和红色项目。这就是您在结果中获得红色项目大小的原因。
How do you set to aggregate only on the filtered subset where it matches all documents?
我不确定是否理解您的问题,因为您过滤的子集同时包含红色和蓝色项。您可以使用子聚合 (https://www.elastic.co/blog/intro-to-aggregations-pt-2-sub-aggregations) 在结果中按颜色显示大小
更新 1:
If blue and red are selected, and M is only for blue products, but L is for both red and blue, I want to only return L
因此您希望尺寸取决于颜色
"aggs": {
"price": {
"stats": {
"field": "price"
}
},
"discounted": {
"terms": {
"field": "discounted"
}
},
"stock": {
"filter": {
"range": {
"stock": {
"gt": 0
}
}
}
},
"colour": {
"terms": {
"field": "colour"
},
"aggs": {
"size": {
"terms": {
"field": "size"
}
}
}
}
}
您可以使用子聚合来执行此操作(https://www.elastic.co/blog/intro-to-aggregations-pt-2-sub-aggregations)
更新 2:
讨论后的最终答案,保留OR查询的结果,但聚合中只保留AND查询的结果
{
"aggs": {
"colorsizes": {
"filters": {
"filters": [{
"bool": {
"must": [{
"term": {
"size": "red"
}
}, {
"term": {
"size": "blue"
}
}]
}
}]
},
"aggs": {
"size": {
"terms": {
"field": "size"
}
}
}
}
}
}
对于电子商务过滤系统,必须在整个过滤集上计算 ElasticSearch 中的聚合。
没有过滤器,我们得到:
"filters":{
"colour":{
"red":{
"count":5
},
"blue":{
"count":4
}
},
"size":{
"L":{
"count":16
},
"M":{
"count":15
}
}
}
仅过滤红色,我们得到:
"filters":{
"colour":{
"red":{
"count":5
},
"blue":{
"count":3
}
},
"size":{
"L":{
"count":1
},
"M":{
"count":1
}
}
}
只过滤蓝色,我们得到:
"filters":{
"colour":{
"blue":{
"count":4
},
"red":{
"count":3
}
}
}
蓝色没有尺码,没关系。但是,如果我们将两者结合起来:
"filters":{
"colour":{
"red":{
"count":5
},
"blue":{
"count":4
}
},
"size":{
"L":{
"count":1
},
"M":{
"count":1
}
根本不应返回尺码,因为它与两种颜色都不匹配。
这是发送给 ES 的内容:
{
"size":1000,
"fields":[
"id",
"name",
"price",
"colour",
"size"
],
"query":{
"filtered":{
"query":{
"match_all":{}
},
"filter":{
"bool":{
"must":[
{
"term":{
"categories":4838
}
},
{
"bool":{
"should":[
{
"term":{
"colour":"blue"
}
},
{
"term":{
"colour":"red"
}
}
]
}
}
]
}
}
}
},
"aggs":{
"price":{
"stats":{
"field":"price"
}
},
"discounted":{
"terms":{
"field":"discounted"
}
},
"stock":{
"filter":{
"range":{
"stock":{
"gt":0
}
}
}
},
"colour":{
"terms":{
"field":"colour"
}
},
"size":{
"terms":{
"field":"size"
}
}
}
}
出了什么问题?如何设置仅在匹配所有文档的过滤子集上聚合?
结果与查询一致
{
"bool": {
"must": [{
"term": {
"categories": 4838
}
}, {
"bool": {
"should": [{
"term": {
"colour": "blue"
}
}, {
"term": {
"colour": "red"
}
}]
}
}]
}
}
您要的是蓝色 或 红色的类别 4838 的商品。当您对大小执行聚合时,会为数据集中的每个大小创建存储桶,其中包含类别 4838 的蓝色和红色项目。这就是您在结果中获得红色项目大小的原因。
How do you set to aggregate only on the filtered subset where it matches all documents?
我不确定是否理解您的问题,因为您过滤的子集同时包含红色和蓝色项。您可以使用子聚合 (https://www.elastic.co/blog/intro-to-aggregations-pt-2-sub-aggregations) 在结果中按颜色显示大小
更新 1:
If blue and red are selected, and M is only for blue products, but L is for both red and blue, I want to only return L
因此您希望尺寸取决于颜色
"aggs": {
"price": {
"stats": {
"field": "price"
}
},
"discounted": {
"terms": {
"field": "discounted"
}
},
"stock": {
"filter": {
"range": {
"stock": {
"gt": 0
}
}
}
},
"colour": {
"terms": {
"field": "colour"
},
"aggs": {
"size": {
"terms": {
"field": "size"
}
}
}
}
}
您可以使用子聚合来执行此操作(https://www.elastic.co/blog/intro-to-aggregations-pt-2-sub-aggregations)
更新 2:
讨论后的最终答案,保留OR查询的结果,但聚合中只保留AND查询的结果
{
"aggs": {
"colorsizes": {
"filters": {
"filters": [{
"bool": {
"must": [{
"term": {
"size": "red"
}
}, {
"term": {
"size": "blue"
}
}]
}
}]
},
"aggs": {
"size": {
"terms": {
"field": "size"
}
}
}
}
}
}