我有一个索引test
,其中包含以下文档:
POST /test/page/a
{
"Id": "a",
"Parent": "0"
}
POST /test/page/b
{
"Id": "b",
"Parent": "a"
}
POST /test/page/c
{
"Id": "c",
"Parent": "a"
}
POST /test/page/d
{
"Id": "d",
"Parent": "c"
}
也就是说,在逻辑页面
层次结构中,如下所示:
0 (non existant)
|
`- a
|
> b
|
` c
|
` d
我可以找到所有 Parent
等于 a
的 page
。我只是:
POST /test/page/_search
{
"query": {
"term": {
"Parent": "a"
}
}
}
答案(缩写):
{
"hits": {
"total": 2,
"hits": [
{
"_index": "test",
"_type": "page",
"_id": "b",
"_source": {
"Id": "b",
"Parent": "a"
}
},
{
"_index": "test",
"_type": "page",
"_id": "c",
"_source": {
"Id": "c",
"Parent": "a"
}
}
]
}
}
现在,在客户端,我可以构建根元素及其直接子元素的 TreeView 。
但是,我还想知道(刚刚列出的) child 的直系 child 数量。
我想要一个类似于以下内容的答案:
{
"hits": {
"total": 2,
"hits": [
{
"_index": "test",
"_type": "page",
"_id": "b",
"_source": {
"Id": "b",
"Parent": "a"
},
"_numberOfChildren": 1
},
{
"_index": "test",
"_type": "page",
"_id": "c",
"_source": {
"Id": "c",
"Parent": "a"
},
"_numberOfChildren": 0
}
]
}
}
我希望 ES 在某种“子查询”中动态计算 _numberOfChildren
。
答案可能是聚合吗?
最佳答案
如果您没有很多元素:
您只需使用一个查询即可检索信息:
GET /test/page/_search
{
"filter": {
"term": {
"Parent": "0"
}
},
"aggs": {
"numberOfChildren": {
"terms": {
"field": "Parent",
"size": 0
}
}
}
}
在响应中,hits.hits
将包含 0
的子级。
对于每个节点,您将在 aggregations.numberOfChildren.buckets
中拥有其子节点数量,其结构如下:
{
"key": [page id],
"doc_count": [number of children for this page]
}
响应示例:
{
...
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "test",
"_type": "page",
"_id": "a",
"_score": 1,
"_source": {
"Id": "a",
"Parent": "0"
}
}
]
},
"aggregations": {
"numberOfChildren": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "0",
"doc_count": 1
},
{
"key": "a",
"doc_count": 2
},
{
"key": "c",
"doc_count": 1
}
]
}
}
请注意:
- 如果页面没有任何子级,则它不会出现在列表中。
- 您拥有所有 parent 的 child 数量,而不仅仅是直接 parent 的 child 数量
0
的子级,因此如果您有很多项目(太多 桶)。
如果您有很多元素:
最简单的方法是使用两个查询:GET /test/page/_search
{
"query": {
"filtered": {
"filter": {
"term": {
"Parent": "0"
}
}
}
}
}
您将在 hits.hits
中拥有 0 的直接子级。
GET /test/page/_search
{
"size": 0,
"query": {
"filtered": {
"filter": {
"terms": {
"Parent": [
"a" // list 0's direct children ids
]
}
}
}
},
"aggs": {
"numberOfChildren": {
"terms": {
"field": "Parent",
"size": 0,
"order": {
"_term": "asc"
}
}
}
}
}
您将在 aggregations.numberOfChildrens.buckets
中获得 0 的直接子代的子代数量
您也许还可以使用脚本,但我不确定它们是否可以在这种情况下工作。
亲子关系对你没有帮助,因为 parent 和 child 不可能是同一类型。
关于elasticsearch - 计算 Elasticsearch 中的子页面数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36667051/