Монгрирование базы данных Mongo с $ project и $ filter: $ add и $ subtract возвращают ноль - PullRequest
0 голосов
/ 21 сентября 2018

Так что я выполняю довольно большой запрос агрегации в оболочке mongo (только для целей тестирования)

на моем последнем шаге $ project, я использую $ filter для выбора диапазона элементов.

$filter: {
                "input": "$users",
                "as": "users",
                "cond": {
                    $and: [
                            { 
                                $lte: [
                                    "$$users.ranking",
                                    {$add: ["$myUser[0].ranking", 5]}
                                ] 

                            },
                            { 
                              $gte: [
                                    "$$users.ranking",
                                    {$subtract: ["$myUser[0].ranking", 5]}
                                ] 

                            }

                    ]
                }
           }   

$ subtract и $ add оба возвращают null, есть идеи, как мне это исправить?

MongoVersion: 3.6.3, работающий в док-контейнере с использованием образа mongo 3.6.3.

Правильный вывод должен быть:

"users" : [
        {
            "_id" : ObjectId("5ba3c2089a3a3e26a859f11b"),
            "sgId" : ObjectId("5b76c1040c3aa5000559e6b3"),
            "score" : 30,
            "ranking" : NumberLong("0")
        },
        {
            "_id" : ObjectId("5ba3c1d89a3a3e26a859f11a"),
            "sgId" : ObjectId("5b76c1000c3aa500060e0fd2"),
            "score" : 20,
            "ranking" : NumberLong("1")
        },
        {
            "_id" : ObjectId("5ba4fa3b71936b33e46569b9"),
            "sgId" : ObjectId("5b76c8a3f7d606000566b652"),
            "score" : 10,
            "ranking" : NumberLong("2")
        },
        {
            "_id" : ObjectId("5ba4fa4c71936b33e46569ba"),
            "sgId" : ObjectId("5b76cafbf7d6060006270c90"),
            "score" : 9,
            "ranking" : NumberLong("3")
        },
        {
            "_id" : ObjectId("5ba4fe6e71936b33e46569bb"),
            "sgId" : ObjectId("5b7a4e69f7d606000566b65f"),
            "score" : 8,
            "ranking" : NumberLong("4")
        },
        {
            "_id" : ObjectId("5ba4fe7471936b33e46569bc"),
            "sgId" : ObjectId("5b7a4f47f7d6060006270cc4"),
            "score" : 7,
            "ranking" : NumberLong("5")
        },
        {
            "_id" : ObjectId("5ba4fe8871936b33e46569bd"),
            "sgId" : ObjectId("5b7a5265f7d606000566b67e"),
            "score" : 6,
            "ranking" : NumberLong("6")
        }
    ]

Полный запрос:

db.highscore.aggregate([
    {
        $sort: {score: -1}

    },
    {
        $group: {
        "_id": false,
        "users": {
            $push: {
                "_id": "$_id",
                "sgId": "$sgId",
                "score": "$score",
            }
        }
    }

    },
    {
        $unwind: {
            "path": "$users",
           "includeArrayIndex": "ranking"
        }
    },
    {
        $group: {
            "_id": false,
            "users": {
                $push: {
                   "_id": "$users._id",
                   "sgId": "$users.sgId",
                   "score": "$users.score",
                   "ranking": "$ranking"
               }
           }
       }
    },
    {
        $project: {
            "users": "$users",
            "myUser": {
                $filter: {
                    "input": "$users",
                    "as": "user",
                    "cond": {
                        $eq: ["$$user.sgId", ObjectId("5b76c1000c3aa500060e0fd2")]
                    }
                }
            }
        }
    },
    {
       $project: {
           "myUser": "$myUser",
           "users" : {
               $filter: {
                   "input": "$users",
                    "as": "users",
                    "cond": {
                        $and: [
                                { 
                                    $lte: [
                                        "$$users.ranking",
                                        {$add: ["$myUser[0].ranking", NumberLong("5")]}
                                    ] 

                                },
                                { 
                                  $gte: [
                                        "$$users.ranking",
                                        {$subtract: ["$myUser[0].ranking", NumberLong("5")]}
                                    ] 

                               }

                        ]
                    }
               }
           }
       }
    },
])

Использованные документы:

{
    "_id" : ObjectId("5ba3c1d89a3a3e26a859f11a"),
    "sgId" : ObjectId("5b76c1000c3aa500060e0fd2"),
    "type" : "a",
    "score" : 20,
    "created" : ISODate("2018-09-20T17:50:48.024+02:00")
},
{
    "_id" : ObjectId("5ba3c2089a3a3e26a859f11b"),
    "sgId" : ObjectId("5b76c1040c3aa5000559e6b3"),
    "type" : "a",
    "score" : 30,
    "created" : ISODate("2018-09-20T17:51:36.258+02:00")
},
{
    "_id" : ObjectId("5ba4fa3b71936b33e46569b9"),
    "sgId" : ObjectId("5b76c8a3f7d606000566b652"),
    "type" : "a",
    "score" : 10,
    "created" : ISODate("2018-09-20T17:50:48.024+02:00")
},
{
    "_id" : ObjectId("5ba4fa4c71936b33e46569ba"),
    "sgId" : ObjectId("5b76cafbf7d6060006270c90"),
    "type" : "a",
    "score" : 9,
    "created" : ISODate("2018-09-20T17:50:48.024+02:00")
}

1 Ответ

0 голосов
/ 21 сентября 2018

Нашел, мне просто нужно было добавить $ unwind перед последним проектом $, чтобы преобразовать массив myUser в объект - тогда я смог добраться до него для добавления.

Итак, полный конвейер, чтобы получитьрейтинг списка рекордов и диапазона с вашим данным пользователем в качестве источника.

db.highscore.aggregate([
    {
        $sort: {score: -1}

    },
    {
        $group: {
        "_id": false,
        "users": {
            $push: {
                "_id": "$_id",
                "sgId": "$sgId",
                "score": "$score",
            }
        }
    }

    },
    {
        $unwind: {
            "path": "$users",
           "includeArrayIndex": "ranking"
        }
    },
    {
        $group: {
            "_id": false,
            "users": {
                $push: {
                   "_id": "$users._id",
                   "sgId": "$users.sgId",
                   "score": "$users.score",
                   "ranking": "$ranking"
               }
           }
       }
    },
    {
        $project: {
            "users": "$users",
            "myUser": {
                $filter: {
                    "input": "$users",
                    "as": "user",
                    "cond": {
                        $eq: ["$$user.sgId", ObjectId("5b76c1000c3aa500060e0fd2")]
                    }
                }
            }
        }
    },
    {
        $unwind: {
            path: '$myUser'
        }
    },
   {
       $project: {
           "myUser": "$myUser",
           "users" : {
               $filter: {
                   "input": "$users",
                    "as": "users",
                    "cond": {
                        $and: [
                                { 
                                    $lte: [
                                        "$$users.ranking",
                                        {$add: ["$myUser.ranking", NumberLong("2")]}
                                    ] 

                                },
                                { 
                                  $gte: [
                                        "$$users.ranking",
                                        {$subtract: ["$myUser.ranking", NumberLong("2")]}
                                    ] 

                               }

                        ]
                    }
               }
           }
       }
    },
], {'allowDiskUse': true})
...