MongoDB Mgo Sort Skip Limit 聚合管道 - 结果乱序
MongoDB Mgo Sort Skip Limit Aggregation Pipeline - Results out of order
我有一份文档 "item" 如下所示:
{
"_id" : ObjectId("5a146ce6cca59f21e897589b"),
"platform" : "example_platform",
"mp_id" : "example_marketplace_id",
"category" : {
"platform" : "example_platform",
"id" : 999,
"name" : "example_category_name"
},
"image_urls" : [
"http://example.com/image.jpg"
],
"title" : "example_title",
"seller" : {
"username" : "example_username",
"platform" : "example_platform",
},
"quantity_sold" : 100,
"sales" : [
{
"_id" : ObjectId("5a146cf3cca59f21e8975951"),
"time" : ISODate("2017-09-09T04:07:36.000Z"),
"amount" : 31.4500007629395,
"currency" : "USD",
"buyer" : {
"username" : "example_username",
"platform" : "example_platform",
},
"item_id" : ObjectId("5a146ce6cca59f21e897589b")
},
{
"_id" : ObjectId("5a146cf3cca59f21e8975952"),
"time" : ISODate("2017-11-16T01:24:10.000Z"),
"amount" : 27.0900001525879,
"currency" : "USD",
"buyer" : {
"username" : "example_username",
"platform" : "example_platform",
},
"item_id" : ObjectId("5a146ce6cca59f21e897589b")
}
]
}
我想做的是能够查询 db 以在给定时间范围内按商品售出次数对商品进行排序,并使用 skip 和 limit(或其他一些方法)对这些结果进行分页方法)。
这是我的聚合 query/pipeline 目前的样子:
func (this SellerItemsQuery) MakePipeline() []bson.M{
var pipeline = []bson.M{
{"$match": bson.M{
"seller.username": this.Username,
"seller.platform": this.Platform,
}}}
if !this.SalesFromDate.Equal(time.Time{}) && !this.SalesToDate.Equal(time.Time{}) {
pipeline = append(pipeline, bson.M{
"$addFields": bson.M{
"sales": bson.M{
"$filter": bson.M{
"input": "$sales",
"as": "sale",
"cond": bson.M{"$and": []bson.M{{"$gte": []interface{}{"$$sale.time", this.SalesFromDate}}, {"$lte": []interface{}{"$$sale.time", this.SalesToDate}}}},
},
},
},
})
}
pipeline = append(pipeline, bson.M{
"$addFields": bson.M{
"num_sales": bson.M{
"$size": bson.M{
"$ifNull": []interface{}{
"$sales", []interface{}{},
},
},
},
},
})
pipeline = append(pipeline, bson.M{
"$sort": bson.M{"num_sales": -1,
"_id": 1},
}, bson.M{
"$skip": this.Skip,
}, bson.M{
"$limit": this.Limit,
})
return pipeline
当前的问题是 returns 结果非常不一致。一次按 25 个项目分页时(skip=0&limit=25、skip=25&limit=25 等)。第一个结果集通常是正确的,给定时间段内最畅销的商品出现在顶部,销售数量按预期下降,但是到第二、第三或第四组 25 个结果几乎完全随机。集合中的项目销售数量将突然下降到零,而下一组将包括具有 3 个销售的项目,等等。完全乱序,重复的项目也会出现,即使我已经包含了一个排序 { _id: 1} 在管道中,我认为这可以解决这个问题。
问题是 bson.M 结构是无序的,所以有时它会在按 "num_sales" 字段排序之前先按“_id”字段排序,这会导致结果集乱序。改为使用 bson.D 有序对:
bson.M{
"$sort": bson.M{"num_sales": -1,
"_id": 1},
},
变成:
bson.M{
"$sort": bson.D{{"num_sales", -1},
{"_id", 1}},
},
我有一份文档 "item" 如下所示:
{
"_id" : ObjectId("5a146ce6cca59f21e897589b"),
"platform" : "example_platform",
"mp_id" : "example_marketplace_id",
"category" : {
"platform" : "example_platform",
"id" : 999,
"name" : "example_category_name"
},
"image_urls" : [
"http://example.com/image.jpg"
],
"title" : "example_title",
"seller" : {
"username" : "example_username",
"platform" : "example_platform",
},
"quantity_sold" : 100,
"sales" : [
{
"_id" : ObjectId("5a146cf3cca59f21e8975951"),
"time" : ISODate("2017-09-09T04:07:36.000Z"),
"amount" : 31.4500007629395,
"currency" : "USD",
"buyer" : {
"username" : "example_username",
"platform" : "example_platform",
},
"item_id" : ObjectId("5a146ce6cca59f21e897589b")
},
{
"_id" : ObjectId("5a146cf3cca59f21e8975952"),
"time" : ISODate("2017-11-16T01:24:10.000Z"),
"amount" : 27.0900001525879,
"currency" : "USD",
"buyer" : {
"username" : "example_username",
"platform" : "example_platform",
},
"item_id" : ObjectId("5a146ce6cca59f21e897589b")
}
]
}
我想做的是能够查询 db 以在给定时间范围内按商品售出次数对商品进行排序,并使用 skip 和 limit(或其他一些方法)对这些结果进行分页方法)。
这是我的聚合 query/pipeline 目前的样子:
func (this SellerItemsQuery) MakePipeline() []bson.M{
var pipeline = []bson.M{
{"$match": bson.M{
"seller.username": this.Username,
"seller.platform": this.Platform,
}}}
if !this.SalesFromDate.Equal(time.Time{}) && !this.SalesToDate.Equal(time.Time{}) {
pipeline = append(pipeline, bson.M{
"$addFields": bson.M{
"sales": bson.M{
"$filter": bson.M{
"input": "$sales",
"as": "sale",
"cond": bson.M{"$and": []bson.M{{"$gte": []interface{}{"$$sale.time", this.SalesFromDate}}, {"$lte": []interface{}{"$$sale.time", this.SalesToDate}}}},
},
},
},
})
}
pipeline = append(pipeline, bson.M{
"$addFields": bson.M{
"num_sales": bson.M{
"$size": bson.M{
"$ifNull": []interface{}{
"$sales", []interface{}{},
},
},
},
},
})
pipeline = append(pipeline, bson.M{
"$sort": bson.M{"num_sales": -1,
"_id": 1},
}, bson.M{
"$skip": this.Skip,
}, bson.M{
"$limit": this.Limit,
})
return pipeline
当前的问题是 returns 结果非常不一致。一次按 25 个项目分页时(skip=0&limit=25、skip=25&limit=25 等)。第一个结果集通常是正确的,给定时间段内最畅销的商品出现在顶部,销售数量按预期下降,但是到第二、第三或第四组 25 个结果几乎完全随机。集合中的项目销售数量将突然下降到零,而下一组将包括具有 3 个销售的项目,等等。完全乱序,重复的项目也会出现,即使我已经包含了一个排序 { _id: 1} 在管道中,我认为这可以解决这个问题。
问题是 bson.M 结构是无序的,所以有时它会在按 "num_sales" 字段排序之前先按“_id”字段排序,这会导致结果集乱序。改为使用 bson.D 有序对:
bson.M{
"$sort": bson.M{"num_sales": -1,
"_id": 1},
},
变成:
bson.M{
"$sort": bson.D{{"num_sales", -1},
{"_id", 1}},
},