Как использовать $ filter во вложенном дочернем массиве с mongodb? - PullRequest
1 голос
/ 02 февраля 2020

Мои данные mongodb такие, я хочу отфильтровать memoryLine.

{
"_id" : ObjectId("5e36950f65fae21293937594"),
"userId" : "5e33ee0b4a3895a6d246f3ee",
"notes" : [ 
    {
        "noteId" : ObjectId("5e36953665fae212939375a0"),
        "time" : ISODate("2020-02-02T17:24:06.460Z"),
        "memoryLine" : [ 
            {
                "_id" : ObjectId("5e36953665fae212939375ab"),
                "memoryTime" : ISODate("2020-02-03T17:54:06.460Z")
            }, 
            {
                "_id" : ObjectId("5e36953665fae212939375aa"),
                "memoryTime" : ISODate("2020-02-03T05:24:06.460Z")
            }
        ]
    }
]}

Я хочу получить элемент, память которого больше, чем ожидалось, как сейчас,

"userId" : "5e33ee0b4a3895a6d246f3ee",
"notes" : [ 
    {
    "noteId" : ObjectId("5e36953665fae212939375a0"),
    "time" : ISODate("2020-02-02T17:24:06.460Z"),
    "memoryLine" : [ 
        {
            "_id" : ObjectId("5e36953665fae212939375ab"),
            "memoryTime" : ISODate("2020-02-03T17:54:06.460Z")
        }, 
        {
            "_id" : ObjectId("5e36953665fae212939375aa"),
            "memoryTime" : ISODate("2020-02-03T05:24:06.460Z")
        }
    ]
}]

так же используйте код, как показано ниже. Я использую $ filter в memoryLine для фильтрации, чтобы получить нужный элемент.

aggregate([{
    $match: {
        "$and": [
            { userId:  "5e33ee0b4a3895a6d246f3ee"},
        ]
    }
}, {
    $project: {
        userId: 1,
        notes: {
            noteId: 1,
            time: 1,
            memoryLine: {
                $filter: {
                    input: "$memoryLine",
                    as: "mLine",
                    cond: { $gt: ["$$mLine.memoryTime", new Date(new Date().getTime() + 8 * 1000 * 3600)] }
                }
            }
        }
    }
}]).then(doc => {
    res.json({
        code: 200,
        message: 'success',
        result: doc
    })
});

но я получил это, memoryLine имеет значение null, почему? Я пытаюсь изменить $ gt до $ lt, но также имеет значение null.

"userId" : "5e33ee0b4a3895a6d246f3ee",
"notes" : [ 
    {
    "noteId" : ObjectId("5e36953665fae212939375a0"),
    "time" : ISODate("2020-02-02T17:24:06.460Z"),
    "memoryLine" : null  <<<-------------  here is not right
}]

1 Ответ

1 голос
/ 02 февраля 2020

Вы можете использовать $ addFields для замены существующего поля, $ map для внешней коллекции и $ filter для внутренней:

db.collection.aggregate([
    {
        $addFields: {
            notes: {
                $map: {
                    input: "$notes",
                    in: {
                        $mergeObjects: [
                            "$$this",
                            { 
                                memoryLine: {
                                    $filter: {
                                        input: "$$this.memoryLine",
                                        as: "ml",
                                        cond: {
                                            $gt: [ "$$ml.memoryTime", new Date() ]
                                        }
                                    }
                                }
                            }
                        ]
                    }
                }
            }
        }
    }
])

$ mergeObjects используется, чтобы избежать повторения полей из исходного объекта memoryLine.

Пн go Детская площадка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...