如何编写查询来检索每个匹配的子文档数组
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 的嵌入式文档中检索数组的最后一个对象?