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}},
    },