MogoDB子文件过滤

时间:2018-01-07 06:15:01

标签: mongodb mongodb-query

  {
        "_id" : ObjectId("5a4e43edb85ed11cd4dcba45"),
        "email" : "av@gmail.com",
        "username" : "alpesh",
        "subscriptions" : [ 
            {
                "sub_id" : "5a4df654b9799b79147f9361",
                "activation_date" : ISODate("2017-12-19T18:30:00.000Z"),
                "expiry_date" : ISODate("2018-01-19T18:30:00.000Z")
            }, 
            {
                "sub_id" : "5a4df654b9799b79147f9361",
                "activation_date" : ISODate("2018-01-19T18:30:00.000Z"),
                "expiry_date" : ISODate("2018-02-19T18:30:00.000Z")
            }, 
            {
                "sub_id" : "5a51a925ddc5003b68cc38b3",
                "activation_date" : ISODate("2018-02-19T18:30:00.000Z"),
                "expiry_date" : ISODate("2018-03-22T18:30:00.000Z")
            }
        ]
    }

我试过这个.. db.find({" subscriptions.sub_id":" 5a4df654b9799b79147f9361"}); 它返回..

{
    "_id" : ObjectId("5a4e43edb85ed11cd4dcba45"),
    "email" : "av@gmail.com",
    "username" : "alpesh",
    "subscriptions" : [ 
        {
            "sub_id" : "5a4df654b9799b79147f9361",
            "activation_date" : ISODate("2017-12-19T18:30:00.000Z"),
            "expiry_date" : ISODate("2018-01-19T18:30:00.000Z")
        }, 
        {
            "sub_id" : "5a4df654b9799b79147f9361",
            "activation_date" : ISODate("2018-01-19T18:30:00.000Z"),
            "expiry_date" : ISODate("2018-02-19T18:30:00.000Z")
        }, 
        {
            "sub_id" : "5a51a925ddc5003b68cc38b3",
            "activation_date" : ISODate("2018-02-19T18:30:00.000Z"),
            "expiry_date" : ISODate("2018-03-22T18:30:00.000Z")
        }
    ]
}

我也试过$ aggregate,$ unwind,$ filter,$ projection和很多方法但是没有一个按预期返回... 我想要所有匹配的子文档...像这样....

   {
        "_id" : ObjectId("5a4e43edb85ed11cd4dcba45"),
        "email" : "av@gmail.com",
        "username" : "alpesh",
        "subscriptions" : [ 
            {
                "sub_id" : "5a4df654b9799b79147f9361",
                "activation_date" : ISODate("2017-12-19T18:30:00.000Z"),
                "expiry_date" : ISODate("2018-01-19T18:30:00.000Z")
            }, 
            {
                "sub_id" : "5a4df654b9799b79147f9361",
                "activation_date" : ISODate("2018-01-19T18:30:00.000Z"),
                "expiry_date" : ISODate("2018-02-19T18:30:00.000Z")
            }
        ]
    }

2 个答案:

答案 0 :(得分:3)

实现这一目标的两种方法。您可以使用$elemMatch作为投影操作符,但这只会为您带来第一个匹配的子文档:

db.collection.find(
    { "subscriptions.sub_id": "5a4df654b9799b79147f9361" },
    { "subscriptions" : { $elemMatch: { "sub_id": "5a4df654b9799b79147f9361" } } }
)

第二种方法是使用聚合框架:

db.collection.aggregate([  
    { $unwind: "$subscriptions" },
    { $match: {"subscriptions.sub_id": "5a4df654b9799b79147f9361"} },
    {
        $group: {
            _id: "$_id",
            "email" : { $first: "$email" },
            "username" : { $first: "$username" },
            "subscriptions": { $push: "$subscriptions" }
        }
    }
])

这里的重点是,您需要将未展开的订阅分组以获取原始形状(过滤后)。要将累积订阅检索到数组,您可以使用$push运算符,并从外部文档中获取属性,您可以从任何匹配的文档移动它们(使用$first$last)。

答案 1 :(得分:3)

db.collection('gyms').aggregate([
    {
        $match: {
            subscriptions: { 
                $elemMatch: { sub_id: "5a4df654b9799b79147f9361" }
            }
        }
    },
    {
        $redact: {
            $cond: {
                if: {
                    $or: [
                        { $eq: ["$sub_id", "5a4df654b9799b79147f9361" ] },
                        { $not: "$sub_id" }
                    ]
                },
                then: "$$DESCEND",
                else: "$$PRUNE"
            }
        }
    }
])

这是在没有不必要的子文档的单个doucment中按预期生成的。

{
    "email": "av@gmail.com",
    "username": "alpesh",
    "subscriptions": [
        {
            "sub_id": "5a4df654b9799b79147f9361",
            "activation_date": "2017-12-19T18:30:00.000Z",
            "expiry_date": "2018-01-19T18:30:00.000Z"
        },
        {
            "sub_id": "5a4df654b9799b79147f9361",
            "activation_date": "2018-01-19T18:30:00.000Z",
            "expiry_date": "2018-02-19T18:30:00.000Z"
        }
    ]
}
相关问题