如何使用快速nodejs从猫鼬中的Id数组中获取所有对象?



我正在开发一个聊天应用程序,我在DB中保存对话列表,像这样;

对话集合:

{ 
members: [ "123", "456" ]
...rest
}

和用户集合:

{
_id: ObjectId( "123" ), name: "anyone"
},
{
_id: ObjectId( "456" ), name: "someone"
}

我想要的结果是:

{
members: [
{_id: ObjectId( "123" ), name: "anyone"},
{_id: ObjectId( "456" ), name: someone"}
]
}

我知道聚合查找是救援,但无法找到一种方法如何从该成员的数组中获取所有id,因为在未来它可以是20到30个id。如果它是一个简单的字段,那么我可以获取,但对于数组,我不能。

我已经试过了

db.conversations.aggregate([
{
"$lookup": {
"from": "users",
"localField": "members",
"foreignField": "_id",
"as": "members_details"
}
}
])

但是它返回members_details: []

您可以使用下面的查询来完成您想要的。您需要使用$lookup,因为您希望从不同的集合收集数据,而不是当前查询的集合。

你可以在这里查看一个现场演示

这是一个更新的实时演示

数据库
db={
"conversations": [
{
members: [
123,
456
]
}
],
"users": [
{
"_id": 123,
"name": "foo"
},
{
"_id": 456,
"name": "bar"
}
]
}
查询

db.conversations.aggregate([
{
"$lookup": {
"from": "users",
"localField": "members",
"foreignField": "_id",
"as": "members"
}
},
{
$project: {
_id: 0,
members: 1
}
}
])
结果

[
{
"members": [
{
"_id": 123,
"name": "foo"
},
{
"_id": 456,
"name": "bar"
}
]
}
]
<标题>

更新在这里查看新的实时演示

新的查询

db.conversations.aggregate([
{
$unwind: "$members"
},
{
"$lookup": {
"from": "users",
"as": "membersFlat",
"let": {
memberObjectId: {
"$toObjectId": "$members"
}
},
pipeline: [
{
$match: {
$expr: {
$eq: [
"$$memberObjectId",
"$_id"
]
}
}
}
]
}
},
{
$group: {
_id: null,
members: {
$push: {
"_id": {
$first: "$membersFlat._id"
},
"name": {
$first: "$membersFlat.name"
}
}
}
}
},
{
$project: {
_id: 0
}
}
])

新结果
[
{
"members": [
{
"_id": ObjectId("124578987898787845658574"),
"name": "foo"
},
{
"_id": ObjectId("124578986532124578986532"),
"name": "bar"
}
]
}
]

由于您的membersid是会话集合中的字符串,您可以将其转换为对象id和连接到用户集合,

  • $addFields更新members数组
  • $map循环members数组
  • $toObjectId将字符串对象id类型转换为对象id类型
db.conversations.aggregate([
{
$addFields: {
members: {
$map: {
input: "$members",
in: {
$toObjectId: "$$this"
}
}
}
}
},
{
$lookup: {
from: "users",
localField: "members",
foreignField: "_id",
as: "members"
}
}
])

游乐场

您可以像这样使用普通的.find():

const members = [
ObjectId('4ed3ede8844f0f351100000c'),
ObjectId('4ed3f117a844e0471100000d'), 
ObjectId('4ed3f18132f50c491100000e')
]
const docs = await model.find({
'_id': { $in: members }
}).exec()

安装猫鼬自动种群。在你的模型代码


import {Schema, model} from 'mongoose';
const modelSchema = new Schema({
...
chats: [{type: Schema.Types.ObjectId, ref: "Chat", autopopulate: true}]
})
modelSchema.plugin(require('mongoose-autopopulate'));
...

相关内容

  • 没有找到相关文章

最新更新