elasticsearch 8 查询文档结果排序?

GET /items/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "status": 1
          }
        }
      ]
    }
  },
  "aggs": {
    "unique_user_ids": {
      "terms": {
        "field": "user_id"
      }
    }
  }, 
  "from": 0,
  "size": 20
}

怎么可以把 查询的文档结果可以按 user_id 聚合的结果排序

--------------------补充-------------

比如上面这个查询,聚合出 user_id, 我想要的结果是 hits 里面的数据按 buckets 统计出这个来的排序,其实就是想找出发布最多文章的前20个用户

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 3060,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
        // ...
    ]
  },
  "aggregations": {
    "unique_user_ids": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 2334,
      "buckets": [
        {
          "key": 255,
          "doc_count": 124
        },
        {
          "key": 34,
          "doc_count": 93
        },
        {
          "key": 150,
          "doc_count": 76
        },
        {
          "key": 67,
          "doc_count": 75
        },
        {
          "key": 175,
          "doc_count": 73
        },
        {
          "key": 146,
          "doc_count": 64
        },
        {
          "key": 19,
          "doc_count": 58
        },
        {
          "key": 113,
          "doc_count": 56
        },
        {
          "key": 35,
          "doc_count": 54
        },
        {
          "key": 91,
          "doc_count": 53
        }
      ]
    }
  }
}
阅读 776
1 个回答

使用 bucket_sort 聚合来排序 user_id 桶,然后使用 top_hits 聚合来获取每个用户的文档。以下是一个示例查询:

GET /items/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "status": 1
          }
        }
      ]
    }
  },
  "aggs": {
    "unique_user_ids": {
      "terms": {
        "field": "user_id",
        "size": 20  // 获取前20个用户
      },
      "aggs": {
        "top_user_hits": {
          "top_hits": {
            "sort": [
              { "_score": { "order": "desc" } }
            ],
            "size": 1  // 每个用户获取一个文档
          }
        },
        "bucket_sort": {
          "bucket_sort": {
            "sort": [
              { "_count": { "order": "desc" } }  // 按文档数量排序
            ],
            "from": 0,
            "size": 20  // 获取前20个用户
          }
        }
      }
    }
  },
  "from": 0,
  "size": 0  // 不返回文档,只返回聚合结果
}

这个查询会按 user_id 聚合文档,并按每个用户的文档数量排序,返回前 20 个用户。每个用户的文档可以通过 top_user_hits 聚合获取。

使用java,可以这样写

SearchRequest req = new SearchRequest.Builder()
    .index("items")
    .query(q -> q.bool(b -> b.must(m -> m
        .match(mm -> mm
                .field("status").query(1)
        )
    )))
    .aggregations("unique_user_ids", a -> a
        .terms(t -> t.field("user_id").size(20))
        .aggregations("top_user_hits", aa -> aa
            .topHits(th -> th.size(1))
        )
        .aggregations("bucket_sort", aa -> aa
            .bucketSort(bs -> bs
                .sort(s -> s
                    .field("_count", SortOrder.Desc)
                )
                .from(0)
                .size(20)
            )
        )
    )
    .from(0)
    .size(0)
    .build();
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏