如何编写查询来检索每个匹配的子文档数组

Posted

技术标签:

【中文标题】如何编写查询来检索每个匹配的子文档数组【英文标题】:How to write Query to retrieve every subdocument array who matches 【发布时间】:2016-04-15 18:23:39 【问题描述】:

在这里我需要清楚地解释我的问题。如何编写查询来检索每个使用 mongoose 和 nodejs 匹配条件的子文档数组。

这是我现有的 JSON:

[

    _id: "568ccd6e646489f4106470ec",
    area_name: "Padi",
    warehouse_name: "Hapserve Online Water Service",
    name: "Ganesh",
    email: "ganesh@excrin.com",
    mobile_no: "9042391491",
    otp: "4466",
    __v: 0,
    date: "06-01-2016",
    booking: 
    [
        
            can_quantity: "4",
            delivery_date: "06-01-2016",
            delivery_timeslot: "10am-3pm",
            subscription: "true",
            subscription_type: "Weekly",
            total_cost: "240",
            order_id: "S13833",
            can_name: "Tata Waters",
            address: "15/A,Ramanrajan street,,Padi,Chennai",
            can_cost: "240",
            _id: "568ccd6e646489f4106470ee",
            ordered_at: "2016-01-06T08:16:46.825Z",
            status: "UnderProcess"
        ,
        
            can_name: "Bisleri",
            can_quantity: "4",
            can_cost: "200",
            delivery_date: "11-01-2016",
            delivery_timeslot: "3pm-8pm",
            order_id: "11537",
            address: "27,Main Street,Padi,Chennai",
            _id: "5693860edb988e241102d196",
            ordered_at: "2016-01-11T10:38:06.749Z",
            status: "UnderProcess"
        
    ]
,

    _id: "56937fb8920629a0164604d8",
    area_name: "Poonamallee",
    warehouse_name: "Tata Waters",
    name: "M.Kalaiselvan",
    email: "kalai131192@gmail.com",
    mobile_no: "9003321521",
    otp: "2256",
    __v: 0,
    date: "2016-01-11T10:11:04.266Z",
    booking: 
    [
        
            can_quantity: "4",
            delivery_date: "06-01-2016",
            delivery_timeslot: "10am-3pm",
            subscription: "true",
            subscription_type: "Alternate",
            total_cost: "640",
            order_id: "S13406",
            can_name: "Kinley",
            address: "133,Bajanai koil street, Melmanagar,Poonamallee,Chennai",
            can_cost: "160",
            _id: "56937fb8920629a0164604da",
            ordered_at: "11-01-2016",
            status: "UnderProcess"
        ,
        
            can_name: "Tata Waters",
            can_quantity: "2",
            can_cost: "120",
            delivery_date: "11-01-2016",
            delivery_timeslot: "10am-3pm",
            order_id: "11387",
            address: "140,Bajanai koil street, Melmanagar,Poonamallee,Chennai",
            _id: "56937ff7920629a0164604dc",
            ordered_at: "2016-01-11T10:12:07.719Z",
            status: "UnderProcess"
        ,
        
            can_name: "Bisleri",
            can_quantity: "4",
            can_cost: "200",
            delivery_date: "12-01-2016",
            delivery_timeslot: "10am-3pm",
            order_id: "16853",
            address: "140,Bajanai koil street, Melmanagar,Poonamallee,Chennai",
            _id: "56938584db988e241102d194",
            ordered_at: "2016-01-11T10:35:48.911Z",
            status: "UnderProcess"
        ,
        
            can_name: "Hapserve",
            can_quantity: "6",
            can_cost: "150",
            delivery_date: "11-01-2016",
            delivery_timeslot: "10am-3pm",
            order_id: "17397",
            address: "133,Bajanai koil street, Melmanagar,Poonamallee,Chennai",
            _id: "569385bbdb988e241102d195",
            ordered_at: "2016-01-11T10:36:43.918Z",
            status: "UnderProcess"
        ,
        
            can_name: "Bisleri",
            can_quantity: "5",
            can_cost: "250",
            delivery_date: "11-01-2016",
            delivery_timeslot: "10am-3pm",
            order_id: "14218",
            address: "133,Bajanai koil street, Melmanagar,Poonamallee,Chennai",
            _id: "56939a13c898ef7c0cc882b0",
            ordered_at: "2016-01-11T12:03:31.324Z",
            status: "Cancelled"
        
    ]
  
]

在这里我需要检索今天交货日期的每个文档

这是我的 nodejs 路线

router.get('/booking-date/:date', function(req, res)
        var id = req.params.date;
        RegisterList.find('booking.delivery_date':id, 'booking.$':1, function(err, docs)
            if(err)
                throw err;
            res.json(docs);
        );
    );

虽然我正在使用它,但无法获取所有数据。从集合中只检索到两个数据。

例如,如果我搜索 2016 年 11 月 1 日的日期,我只得到一个子文档 每个父 ID,但在 2016 年 11 月 1 日的上述 json 中。对于一个父 id 有 2 个该日期的子文档,另一个父 id 有 1 个该日期的子文档。

我无法将猫鼬查询检索写入每个匹配完成的子文档.. 帮助将不胜感激...

【问题讨论】:

【参考方案1】:

听起来您可能想尝试 aggregation framework,您可以在其中 $project 使用 $setDifference 提供过滤器的预订数组$map$cond 运算符。

$map 运算符检查 booking 数组中的每个元素,$cond 运算符仅根据 true 条件返回所需字段,false相反返回值而不是数组元素。 $setDifference 运算符然后通过与另一个具有 [false] 值的集合进行比较,从数组中删除所有 false 值,最终结果仅是返回的匹配项:

router.get('/booking-date/:date', function(req, res)
    var id = req.params.date,
        pipeline = [
            
                "$match":  'booking.delivery_date': id 
            ,
             
                "$project":         
                    "booking":  
                        "$setDifference": [
                             
                                "$map": 
                                    "input": "$booking",
                                    "as": "el",
                                    "in": 
                                        "$cond": [
                                             "$eq": [ "$$el.delivery_date", id ] ,
                                            "$$el",
                                            false
                                        ]
                                    
                                
                            ,
                            [false]
                        ]
                    
                
            
        ];

    RegisterList.aggregate(pipeline, function(err, docs)
        if(err) throw err;
        res.json(docs);
    );
);

【讨论】:

我怎样才能在上面的答案@chridam 中添加另一个条件 @Nodemon 请为此创建一个新问题。【参考方案2】:

$ 投影运算符只投影第一个匹配元素,参考here

投影所有子文档 bookings: 1,然后在您的应用程序中过滤子文档。

【讨论】:

以上是关于如何编写查询来检索每个匹配的子文档数组的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Mongoose 的嵌入式文档中检索数组的最后一个对象?

Mongo:如何仅检索与某些属性匹配的子文档

如何编写一个 solr 查询来检索数字字段值小于指定值的所有记录?

如何组合 2 个 SQL 查询并检索累积计数?

如何匹配 MongoDB 中的子文档数组?

如何使用python脚本从mongoDB中检索数组中的子文档