在ES中执行此等效操作遇到麻烦:
SELECT COUNT(*)
FROM
(
SELECT current_place
FROM `request`
WHERE user_id = '3'
ORDER BY asked_at DESC
LIMIT 10
) sr1
WHERE current_place = '4'
目标是获取用户的10条最近记录(asked_at
是一个时间戳字段),并计算有current_place = '4'
条记录的记录数量
在Elasticsearch中,我没有进行排序,因为我什至没有成功过滤10个元素:
GET /index/type/_search
{
"size": 10,
"query": {
"bool": {
"filter": [
{
"term": {
"user_id": 3
}
},
{
"term": {
"current_place": 4
}
}
]
}
}
}
哪个给我:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 54,
"max_score" : 0.0,
"hits" : [
... truncated, 10 records ...
]
}
}
如何对排序和过滤后的数据进行计数?
编辑:
以下是数据示例:
1 | 2019-03-13 18:28:17
1 | 2019-01-15 16:48:30
1 | 2019-01-15 16:25:32
1 | 2019-01-15 16:19:36
1 | 2019-01-15 15:43:33
1 | 2019-01-15 15:42:05
4 | 2018-11-22 14:14:03
1 | 2018-09-11 11:36:05
4 | 2018-09-11 11:00:49
1 | 2018-08-31 11:19:17 -> 10th line
1 | 2018-08-31 11:19:17
1 | 2018-08-31 11:09:32
1 | 2018-08-27 10:19:04
4 | 2018-08-23 11:56:27
SQL查询返回2
答案 0 :(得分:1)
如果您具有该特定索引的 n 个分片,那么对于Elasticsearch来说是不可能的。
因此,基本上有一个名为terminate after
的功能可用于请求正文搜索,该功能仅考虑每个 shard 中的 n个文档。是的,它适用于分片级别。
假设我的索引具有5
个分片,我想可以在下面的更新查询中使用值2
来查看是否只有10个文档(5个分* 2个文档)检索到了,但是那样行不通,因为一个分片可能只返回1
文档,而其余部分返回2
,最终我最终对9个文档应用了聚合查询。
每个分片的文档减少了,排序结果本身可能无法获取正确的前10个文档。
POST <your_index_name>/_search
{
"size":0,
"terminate_after":2,
"query":{
"bool":{
"filter":[
{
"term":{
"user_id":101
}
}
]
}
},
"sort":[
{
"asked_at":{
"order":"desc"
}
}
],
"aggs":{
"filter_current_place":{
"filter":{
"term":{
"current_place":4
}
},
"aggs":{
"requiredCount":{
"value_count":{
"field":"current_place"
}
}
}
}
}
}
以下是我的回复:
{
"took" : 2,
"timed_out" : false,
"terminated_early" : true,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 9,
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"filter_current_place" : {
"doc_count" : 2,
"requiredCount" : {
"value" : 2
}
}
}
}
请注意,尽管提及我希望每个分片考虑2个文档,但命中仅为9
。当然,该计数似乎是正确的,因为如问题中所述,第9个文档具有current_place:4
。如果它排在第十位呢!
这可能是不正确的,而且很清楚这是什么 这将需要在客户端或服务层完成。
如果是这种情况,那么您只需要执行以下查询,并根据客户端/服务层上的前10个文档处理汇总逻辑。
POST <your_index_name>/_search
{
"size":10,
"query":{
"bool":{
"filter":[
{
"term":{
"user_id":101
}
}
]
}
},
"sort":[
{
"asked_at":{
"order":"desc"
}
}
]
}
注意:上面提到的第一个查询通过Elasticsearch实现此目的的唯一可能方法是,您的索引只有single shard
,而您使用{{1 }}
尽管从技术上讲这不是,但我希望这会有所帮助!