Mongodb查询过滤文档中的嵌套对象数组
Posted
技术标签:
【中文标题】Mongodb查询过滤文档中的嵌套对象数组【英文标题】:Mongo db Query to filter nested array of objects in document 【发布时间】:2018-08-08 10:18:12 【问题描述】:我有以下文件
"userid": "5a88389c9108bf1c48a1a6a7",
"email": "abc@gmail.com",
"lastName": "abc",
"firstName": "xyz",
"__v": 0,
"friends": [
"userid": "5a88398b9108bf1c48a1a6a9",
"ftype": "SR",
"status": "ACCEPT",
"_id": ObjectId("5a9585b401ef0033cc8850c7")
,
"userid": "5a88398b9108bf1c48a1a6a91111",
"ftype": "SR",
"status": "ACCEPT",
"_id": ObjectId("5a9585b401ef0033cc8850c71111")
,
"userid": "5a8ae0a20df6c13dd81256e0",
"ftype": "SR",
"status": "pending",
"_id": ObjectId("5a9641fbbc9ef809b0f7cb4e")
]
,
"userid": "5a88398b9108bf1c48a1a6a9",
"friends": [ ],
"lastName": "123",
"firstName": "xyz",
.......
,
"userid": "5a88398b9108bf1c48a1a6a91111",
"friends": [ ],
"lastName": "456",
"firstName": "xyz",
...
第一个查询
这里我想从好友数组中获取用户 ID,它的状态等于“接受”。 即
[5a88398b9108bf1c48a1a6a9,5a88398b9108bf1c48a1a6a91111]
第二次查询
之后,我必须对同一个集合进行另一个查询,以获取第一个查询中返回的每个用户 ID 的详细信息。
最终查询将返回[5a88398b9108bf1c48a1a6a9,5a88398b9108bf1c48a1a6a91111]
的详细信息
两个用户 ID 即
[
userid" : "5a88398b9108bf1c48a1a6a9",
"lastName" : "123",
"firstName" : "xyz"
,
"userid" : "5a88398b9108bf1c48a1a6a91111",
"lastName" : "456",
"firstName" : "xyz"
]
到目前为止我已经尝试过
Users.find ('_id':5a88389c9108bf1c48a1a6a7,"friends.status":'ACCEPT', (error, users) => )
or
Users.find ('_id':5a88389c9108bf1c48a1a6a7, friends: $elemMatch: status: 'ACCEPT' , (error, users) => )
【问题讨论】:
AlejandroMontilla :我尝试使用以下 mongooes Query 从集合中获取数据Users.find ('userid':5a88389c9108bf1c48a1a6a7, friends: $elemMatch: status: 'ACCEPT' , (error, users) => );
请将find
添加到您的问题中。那find
恢复指定的文档?
您缺少ObjectId("5a88389c9108bf1c48a1a6a7")
=> Users.find( _id:ObjectId("5a88389c9108bf1c48a1a6a7" ))
。也看看$redact
能否请edit 向我们展示您预期的最终输出?
@chridam :非常感谢您为第一个查询所做的努力。它对我来说很好。我想要来自同一文档的所有用户(即 firstQuery 结果)的详细信息。希望你能理解我的查询,谢谢:)
【参考方案1】:
过滤嵌套元素
const products = await Product.aggregate<ProductDoc>([
$match:
userId: data.id,
,
,
$project:
promotions:
$filter:
input: '$promotions',
as: 'p',
cond:
$eq: ['$$p.status', PromotionStatus.Started],
,
,
,
userId: 1,
name: 1,
thumbnail: 1,
,
,
]);
多条件
cond:
$and: [
$eq: [
"$$c.product",
"37sd87hjsdj3"
]
,
$eq: [
"$$c.date",
"date-jan-4-2022"
],
]
,
【讨论】:
【参考方案2】:使用聚合框架的 $map
和 $filter
运算符来处理任务。 $filter
将根据状态应等于"ACCESS"
的指定条件过滤好友数组,$map
会将过滤后数组的结果转换为所需的格式。
对于第二个查询,附加一个 $lookup
管道步骤,该步骤在用户集合上执行自联接以检索与前一个管道中的 id 匹配的文档。
运行以下聚合操作将生成所需的数组:
User.aggregate([
"$match": "friends.status": "ACCEPT" ,
"$project":
"users":
"$map":
"input":
"$filter":
"input": "$friends",
"as": "el",
"cond": "$eq": ["$$el.status", "ACCEPT"]
,
"as": "item",
"in": "$$item.userid"
,
"$lookup":
"from": "users",
"as": "users",
"localField": "users",
"foreignField": "userid"
,
]).exec((err, results) =>
if (err) throw err;
console.log(results[0].users);
);
【讨论】:
谢谢@chridam,第一个查询工作正常 @AnuragGautam 第二个查询需要$lookup
管道,请检查上面的编辑。【参考方案3】:
我没有测试它。只是一个想法,试一试,让我知道。
db.Users.aggregate(
[
$unwind: "$friends"
,
$match: "$friends.status": "ACCEPT"
,
$project: "FriendUserID":"$friends.userid"
,
$lookup:
from:"Users",
as: "FriendsUsers",
localField: "FriendUserID",
foreignField: "userid"
,
$project: FriendsUsers.lastName:1,FriendsUsers.firstName:1
]
)
【讨论】:
感谢@krishan 分享您的观点,但不幸的是它不起作用以上是关于Mongodb查询过滤文档中的嵌套对象数组的主要内容,如果未能解决你的问题,请参考以下文章
如何在mongodb的单个json文档中过滤对象数组? [复制]
将嵌套的 mongoDB 文档转换为平面 pandas DataFrame(对象数组中的对象数组)