$lookup 嵌套对象数组

Posted

技术标签:

【中文标题】$lookup 嵌套对象数组【英文标题】:$lookup on nested array of Objects 【发布时间】:2018-01-27 17:26:06 【问题描述】:

在我的 Node 和 Mongo 项目中,我使用 mongoose 进行建模。 我正在尝试对嵌套文档执行查找。 我有一个线程对象,其中一个“post”对象数组作为它的属性之一。这个嵌套的“post”对象的属性之一是 user_id,即发帖人。 我试图查找 user_id(ie - localfield: thread.post.user_id, from users, foreignfield: _id) 但外壳一直没有返回任何内容。

任何人都可以建议修改我在下面尝试过的内容:

db.threads.aggregate([
 "$match":  "posts._id": ObjectId("abcdef")  ,
 "$sort":  "dateAdded": -1  ,
 "$limit": 15 ,
 "$lookup": "localField": "posts.user_id","from": "users","foreignField": "_id","as": "userinfo" ,
 "$unwind": "$userinfo" ,
 "$project":"dateAdded":1,"userinfo.name":1,"userinfo.username":1
]);

还有我收藏中的记录样本

db.threads.find() 返回...

 
"_id" : ObjectId("78910"), 
"dateAdded" : ISODate("2017-08-18T16:44:23Z"), 
"title" : "Thread Zero", 
"posts" : [  
"_id" : ObjectId("abcdef"), 
"user_id" : ObjectId("12345"), 
"postText" : "good evening", 
"dateAdded" : "2017-8-18 17:44:34"   ],
 "__v" : 0 

db.users.find() 返回...

示例用户对象

 
"_id" : ObjectId("12345"), "name" : "James Free", 
"name" : "Al Isonwunderland", 
"password" : "$2a$10$ILpitvg1.o8X8GnaSaoG4ulnuNWrFTUfhQDA8CdihbHPjBrB8NaVm", 
"username" : "muppet", 
"__v" : 0 

因此,我想从“用户”对象中为线程上的每个帖子返回名称属性。 我写的是试图获取一个特定帖子的用户名广告用户名,我假设检索所有 cmets 的用户名和名称是将 $match 参数留空,允许它返回一个帖子列表带有用户名/用户名

谁能证实这一点?

【问题讨论】:

字段user_id" : "12345" 包含一个“字符串”,您尝试将其与包含ObjectId_id 匹配。因为这两种类型不匹配,所以您不会得到任何结果。因此,您需要修复 user_id 中的数据以包含您在其他集合中引用的相同 ObjectId 值。另请注意,您需要 MongoDB 3.4 才能使用数组中的源。否则,您还需要在$lookup 之前使用早期版本的$unwind 数组。 抱歉,错字。 thread.posts 中的 user_id 应为 ObjectId("12345"),而不是 "12345"。 不,它不是ObjectId("12345"),因为这不是ObjectId 的有效值。如果您需要有关问题的帮助,您需要生成实际数据,而不是一些抽象或混淆。我们无法根据您在此处发布的实际数据来破解您的系统。因此,只需以可复制的方式发布实际数据。见How to create a Minimal, Complete, and Verifiable example。但这肯定是类型不匹配或集合名称不正确。这是没有结果的仅有的两个可能的原因。或者当然是 MongoDB 版本。 【参考方案1】:

我将 ObjectId 换成了 uuid 属性,因为 ObjectId 处理起来很麻烦(Mongo shell 的 .find() 函数返回为 ObjectId("5998a2a81762e90ce9f55d92"),然后从数据库中读取时它只是字母数字("5998a2a81762e90ce9f55d92")返回,然后将该字母数字输入到 shell 以测试命令总是返回 null)

以下解决了我的问题,

db.threads.aggregate([
    $match: uuid: 'de36dd72-238b-47b0-b363-3fbfa1f2743e',
    $unwind:"$posts",
    $lookup: 
        from: 'users', 
        localField: 'posts.user_uuid', 
        foreignField: 'uuid', 
        as: 'userInfo'
]);

这个MongoDB $lookup on nested document 证明有用。 希望这可以帮助其他人

【讨论】:

以上是关于$lookup 嵌套对象数组的主要内容,如果未能解决你的问题,请参考以下文章

合并嵌套在数组 mongoose 中的对象内的 $lookup 值

mongoDB对嵌套对象数组的聚合查找

mongodb $查找带有投影的数组中的嵌套对象

如何仅在猫鼬中使用聚合填充嵌套在对象数组中的字段?

$lookup inside $lookup 在数组中的对象数组中

MongoDB在具有附加字段的对象数组上聚合$lookup