elasticsearch - 计算 Elasticsearch 中的子页面数量

标签 elasticsearch

我有一个索引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 等于 apage。我只是:

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

答案可能是聚合吗?

也许https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-children-aggregation.html

最佳答案

如果您没有很多元素:

您只需使用一个查询即可检索信息:

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/

相关文章:

elasticsearch - Elasticsearch 2.4是否支持.gte功能?

elasticsearch - 如何在ElasticSearch中排序和限制聚合

elasticsearch - 如何将 Elasticsearch 返回的json搜索结果过滤到我的文档中

mysql - MySQL查询到ElasticSearch

elasticsearch - 使用外部托管的Elasticsearch实例进行高级搜索

java - Elasticsearch : "unexpected end of script."

elasticsearch - 如何在范围查询Elasticsearch中提供时间戳

elasticsearch - Spark查询花费的时间太长

elasticsearch - "curl: (52) Empty reply from server"/查询ElastiscSearch超时

elasticsearch - elasticsearch/轮胎:如何定义必须始终匹配的基本搜索条件?