【问题标题】:MongoDB filter array fields within each document of a collectionMongoDB 在集合的每个文档中过滤数组字段
【发布时间】:2019-03-22 20:42:04
【问题描述】:

我有一个MongoDB collection,它的结构是这样的:

/* 1 */
{
    "_id" : ObjectId("5c09a454dd42360001fd2515"),
    "conversations" : {
        "0" : {
            "message" : "Message 1",
              .
              .
              .
        },
        "1" : {
            "message" : "Message 1"
               .
               .
               .
        },
        "2" : {
            "message" : "Message 5"
              .
              .
              .
        },
        "3" : {
            "message" : "Message 1"
              .
              .
              .
        },
        "4" : {
            "message" : "Message 2"
              .
              .
              .
        },
        "5" : {
            "message" : "Message 3"

        },
        "6" : {
            "message" : "compliance"

        },
        "7" : {
            "message" : "Google"

        }
}

/* 2 */
{
    "_id" : ObjectId("5c09a673c2a98f00012f4efb"),

    "conversations" : {
        "0" : {
            "message" : "Message 11"

        },
        "1" : {
            "message" : "Google",

        },
        "2" : {
            "message" : "Message 7"

        }
}

/* 3 */
{
    "_id" : ObjectId("5c09f570173f7900015a82b2"),

    "conversations" : {
        "0" : {
            "message" : "Message 4"
        },

}

.
.
.

在上面的示例数据中,我在collection 中有一组文档,在每个文档中都有一个名为conversations 的字典字段数组。在这个字段中,我有字典字段列表(012...)。我想要做的是过滤每个conversationsfield 中的所有文档,message 值为Message 4

我知道过滤到每个文档中特定字段的方法是db.getCollection('collection_1').find({conversation:""}),但我不知道如何将其应用于字典字段列表,例如我的案例。有什么帮助吗?

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    您需要$objectToArray 运算符将具有未知键的对象转换为kv 字段的数组。然后在$expr 内部,您可以在该数组上应用$filter 以检查是否有任何message 等于"Message 4"

    db.collection.aggregate([
        {
            $match: {
                $expr: {
                    $ne: [
                        {
                            $size: {
                                $filter: {
                                    input: { $objectToArray: "$conversations" },
                                    as: "conv",
                                    cond: { $eq: [ "$$conv.v.message", "Message 4" ] }
                                }
                            }
                        },
                        0
                    ]
                }
            }
        }
    ])
    

    Example

    【讨论】:

    • 以上答案是否非常针对我拥有的示例数据?如果我的文档在conversations 旁边有其他字段怎么办?
    • @user2966197 如果您的密钥是动态生成的,您仍然需要使用$objectToArray,并且它应该仍然可以正常工作,因为conv.v 将包含多个“消息”字段。你可以在这里试试:mongoplayground.net/p/tYJBT_ygKE5
    • 好的。我在查询中的哪个位置指定集合名称?我的收藏名称是“collection_1”,我在上面的查询中没有看到任何地方来指定它?会不会像 db.conversation_1.aggregate()?
    • @user2966197 是的,就像你为.find()做的那样
    猜你喜欢
    • 2021-01-03
    • 2019-01-24
    • 2020-10-16
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    相关资源
    最近更新 更多