как использовать $ filter после $ map сразу в mongoose - PullRequest
1 голос
/ 23 февраля 2020

При использовании js кода я могу использовать функциональное выражение одно за другим, например:

array.map(***).filter(...)

Могу ли я использовать фильтр после карты, как указано выше в пн goose?

У меня такой вопрос. У меня есть набор данных, как показано ниже:

{
"_id" : ObjectId("5e3bd328f3dec754e1b8e17d"),
"userId" : "5e33ee0b4a3895a6d246f3ee",
"userName" : "jackiewillen",
"hasReviewedTimes" : 4,
"notes" : [ 
    {
        "time" : ISODate("2020-02-23T10:12:19.190Z"),
        "memoryLine" : [ 
            {
                "hasReviewed" : false,
                "_id" : ObjectId("5e51df83966daeae41e7f5b1"),
                "memoryTime" : ISODate("2020-02-23T10:42:19.190Z")
            }, 
            {
                "hasReviewed" : false,
                "_id" : ObjectId("5e51df83966daeae41e7f5b0"),
                "memoryTime" : ISODate("2020-02-23T22:12:19.190Z")
            }
        ]
    }, 
    {
        "time" : ISODate("2020-02-23T10:45:26.615Z"),
        "memoryLine" : [ 
            {
                "hasReviewed" : false,
                "_id" : ObjectId("5e51e746966daeae41e7f5bd"),
                "memoryTime" : ISODate("2020-02-23T11:15:26.615Z")
            }, 
            {
                "hasReviewed" : false,
                "_id" : ObjectId("5e51e746966daeae41e7f5bc"),
                "memoryTime" : ISODate("2020-02-23T22:45:26.615Z")
            }
        ]
    }, 
}

Я использую $map, чтобы получить элемент, содержащий memoryTime меньше, чем сейчас в memoryLine, как показано ниже:

db.notes.aggregate([{
    $match: {
        "$and": [
            { userId: '5e33ee0b4a3895a6d246f3ee'}
        ]
    }
}, {
    $project: {
        notes: {
            $map: {
                input: "$notes",
                in: {
                    $mergeObjects: [
                        "$$this",
                        {
                            memoryLine: {
                                $filter: {
                                    input: "$$this.memoryLine",
                                    as: "mLine",
                                    cond: { $lt: ["$$mLine.memoryTime", new Date()] }
                                }
                            }
                        }
                    ]
                },
            },
        }
    }
}
])

мой результат выглядит следующим образом:

"notes": [
        {
            "time": "2020-02-23T10:12:19.190Z",
            "memoryLine": [
                {
                    "hasReviewed": false,
                    "_id": "5e51df83966daeae41e7f5b1",
                    "memoryTime": "2020-02-23T10:42:19.190Z"
                }
            ]
        },
        { //   =====> this item is not needed because of containing empty memoryLine
            "time": "2020-02-23T10:45:26.615Z",
            "memoryLine": [] //  =======> i dont want empty item
        },
   ]

но я хочу получить такой результат:

"notes": [
        {
            "time": "2020-02-23T10:12:19.190Z",
            "memoryLine": [
                {
                    "hasReviewed": false,
                    "_id": "5e51df83966daeae41e7f5b1",
                    "memoryTime": "2020-02-23T10:42:19.190Z"
                }
            ]
        }
   ]

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

db.notes.aggregate([{
    $match: {
        "$and": [
            { userId: '5e33ee0b4a3895a6d246f3ee'}
        ]
    }
}, {
    $project: {
        notes: {
            $map: {
                input: "$notes",
                in: {
                    $mergeObjects: [
                        "$$this",
                        {
                            memoryLine: {
                                $filter: {
                                    input: "$$this.memoryLine",
                                    as: "mLine",
                                    cond: { $lt: ["$$mLine.memoryTime", new Date()] }
                                }
                            }
                        }
                    ],
                    $filter: {
                      input: "$$this",
                      as: "note",
                      cond: { $ne: ["$$note.memoryLine", []] }
                    }
                },
            },
        }
    }
}

Тогда все идет не так.

1 Ответ

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

Вам нужно запустить еще один $filter как отдельный этап конвейера (для удобства чтения) или как самый внешний для вашего текущего $project. Я бы предпочел первый:

{
    $addFields: {
        notes: {
            $filter: {
                input: "$notes",
                cond: {
                    $ne: [ "$$this.memoryLine", [] ]
                }
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...