从聚合中的备用字段返回键值

时间:2014-06-05 23:38:11

标签: elasticsearch

是否可以让Elastic Search根据不同的文档字段返回聚合键?

我们将外来ID和外来名称放在我们的类型中,然后聚合id,但是想要返回名称。名称不是唯一的,因此它们不适合聚合。我知道他们在记录集上也不一定是唯一的,但会接受从该集合中的单个记录中采样的名称。

例如,我们的数据是关于产品的销售情况。每次销售都有与之相关的产品ID和产品名称。

// Sales
{ "product_id": 1, "product_name": "Beer", "quantity": 3, … }
{ "product_id": 1, "product_name": "Beer", "quantity": 2, … }
{ "product_id": 2, "product_name": "Wine", "quantity": 6, … }

查询:

"aggregations": {
    "product": {
      "terms": {
        "field": "product_id"
      },
      "aggregations": {
        "day": {
          "count": {
            "value_count": {
              "field": "quantity"
            }
          }
        }
      }
    }
  }
}

结果:

…
"aggregations": {
  "product": {
    "buckets": [
    {
      "key": "1",
      "doc_count": 2,
      "count": {
        "value": 5
      }
    },{
      "key": "2",
      "doc_count": 1,
      "count": {
        "value": 6
    }
    ]
  }
}
…

通缉结果:

…
"aggregations": {
  "product": {
    "buckets": [
    {
      "key": "Beer",
      "doc_count": 2,
      "count": {
        "value": 5
      }
    },{
      "key": "Wine",
      "doc_count": 1,
      "count": {
        "value": 6
    }
    ]
  }
}
…

在阅读了关于脚本的文档之后,我认为这是不可能的,因为它仅对值进行评估,并且似乎无法访问整个文档(因为它没有' ta doc,但是一组文档。

4 个答案:

答案 0 :(得分:3)

如果仅使用脚本属性(这可以访问整个文档),则可以使用脚本执行此操作。然后将其拆分到您的客户端:例如

"aggs": {
    "types_of": {
      "terms": {
        "script": "doc['product_name'].value + '|' + doc['product_id'].value"
      }
    }
  }

答案 1 :(得分:0)

如果您对索引编制过程拥有所有权力,我建议您根据product_id自行添加新字段(未分析),并在该字段上进行汇总。

我不认为(但我可能会误解)你想做的事情是可能的。

答案 2 :(得分:0)

您可以使用子聚合来获取名称,因此您的查询将类似于:

"aggregations": {
    "product": {
      "terms": {
        "field": "product_id"
      },
      "aggregations": {
        "name": {
          "terms": {
            "field": "product_name"
          }
        },
        "day": {
          "count": {
            "value_count": {
              "field": "quantity"
            }
          }
        }
      }
    }
  }
}

答案 3 :(得分:0)

根据我的理解,该问题希望返回 product_name 以及 product_id 的聚合结果。

这个问题可以通过一个topHit子聚合来解决:

{
    "aggregations": {
        "product": {
            "terms": {
                "field": "product_id"
            },
            "aggregations": {
                "day": {
                    "count": {
                        "value_count": {
                            "field": "quantity"
                        }
                    }
                },
                "topHits": {
                    "top_hits": {
                        "from": 0,
                        "size": 1,
                        "_source": false,
                        "docvalue_fields": [
                            {
                                "field": "product_name"
                            }
                        ]
                    }
                }
            }
        }
    }
}

然后结果看起来像(删除了不必要的字段):

{
    "aggregations": {
        "product": {
            "buckets": [
                {
                    "key": "1",
                    "doc_count": 2,
                    "topHits": {
                        "hits": {
                            "total": {
                                "value": 2,
                                "relation": "eq"
                            },
                            "hits": [
                                {
                                    "fields": {
                                        "product_name": [
                                            "Beer"
                                        ]
                                    }
                                }
                            ]
                        }
                    },
                    "count": {
                        "value": 5
                    }
                }
            ]
        }
    }
}

请注意 countproduct_name 在同一个存储桶中。通过这种方式,我们可以将 product_namecount 联系起来。

注意:如果对product_name进行了分析/归一化,那么返回的结果也会被归一化。为了避免这种情况,我们可以create a sub-field and normalize that field instead