如果为空,则过滤子文档数组,同时仍返回父数据
Posted
技术标签:
【中文标题】如果为空,则过滤子文档数组,同时仍返回父数据【英文标题】:Filter subdocument array while still returning parent data if empty 【发布时间】:2014-07-01 10:01:40 【问题描述】:我正在使用这个问题How to filter array in subdocument with MongoDB的方法
它按预期工作,除非数组中没有任何元素与测试匹配。在这种情况下,我只会得到一个没有父数据的空数组。
样本数据
"_id": "53712c7238b8d900008ef71c",
"dealerName": "TestDealer",
"email": "test@test.com",
"address": ..,
"inventories": [
"title": "active",
"vehicles": [
"_id": "53712fa138b8d900008ef720",
"createdAt": "2014-05-12T20:08:00.000Z",
"tags": [
"vehicle"
],
"opts": ...,
"listed": false,
"disclosures": ...,
"details": ...
,
"_id": "53712fa138b8d900008ef720",
"createdAt": "2014-05-12T20:08:00.000Z",
"tags": [...],
"opts": ...,
"listed": true,
"disclosures": ...,
"details": ...
]
,
"title": "sold",
"vehicles": []
]
努力去做
在我的查询中,我想返回用户(文档)***信息(经销商姓名、电子邮件)和一个名为车辆的属性,其中包含“活动”库存中列出的属性设置为 true
的所有车辆.
我走了多远
这是我的查询。 (我使用 Mongoose,但主要使用原生 Mongo 功能)
$match:
email: params.username
$unwind: '$inventories'
$match:
'inventories.title': 'active'
$unwind:
'$inventories.vehicles'
$match:
'inventories.vehicles.listed':
$eq: true
$group:
_id: '$_id'
dealerName:
$first: '$dealerName'
email:
$first: '$email'
address:
$first: '$address'
vehicles:
$push: '$inventories.vehicles'
问题
起初,我认为我的查询很好,但是,如果没有车辆被标记为listed
,则查询只会返回一个空数组。这是有道理的,因为
$match:
'inventories.vehicles.listed':
$eq: true
不匹配任何内容,但我仍想获取经销商名称以及他的电子邮件
没有车辆匹配时的期望输出
["dealerName": "TestDealer", "email": "test@test.com", vehicles : []]
实际输出
[]
【问题讨论】:
【参考方案1】:在这种情况下,您可以使用 $redact 而不是 $match,就像这样
db.collectionName.aggregate(
$redact:
$cond:
if:$and:[$not:"$dealerName",$not:"$title",$eq:["$listed",false],
then: "$$PRUNE",
else: "$$DESCEND"
)
我们需要第一个条件来跳过***文档,第二个条件跳过第二级,第三个条件来修剪车辆。 在这种情况下不需要 $unwind!
还有一点:$redact 仅在 2.6 中可用
【讨论】:
我认为这不会起作用,因为$cond
必须为真才能使根级和第二级达到第三级。此查询将在根级别修剪文档(它具有字段dealerName
,因此$cond
是false
)。唯一可行的方法是删除前两个条件并将listed:true
添加到根和第二级。以上是关于如果为空,则过滤子文档数组,同时仍返回父数据的主要内容,如果未能解决你的问题,请参考以下文章