2 个模式用户和卡
我将 user.catagories 存储在 user.catagory 下,以及与数组中列出的 catagory.cards 关联的卡片。 我将所有卡片数据存储在卡片架构中。 (见下文)
用户类别
"catagory": [
{
"name": "test",
"createdAt": "2024-02-01T21:47:34.215Z",
"_id": "65bc1176cfb7da6997273ae3",
"cards": [
{
"_id": "65c43a9539206da4c953e334",
"createdAt": "2024-02-08T02:21:09.344Z",
"updatedAt": "2024-02-08T02:21:09.344Z",
"__v": 0
},
{
"_id": "65c43a9539206da4c953e32e",
"createdAt": "2024-02-08T02:21:09.344Z",
"updatedAt": "2024-02-08T02:21:09.344Z",
"__v": 0
},
{
"_id": "65c43a9539206da4c953e332",
"createdAt": "2024-02-08T02:21:09.344Z",
"updatedAt": "2024-02-08T02:21:09.344Z",
"__v": 0
},
{
"_id": "65d2447cbad1f058de61ecca",
"createdAt": "2024-02-18T17:55:08.414Z",
"updatedAt": "2024-02-18T17:55:08.414Z",
"__v": 0
}
]
},
{
"name": "baseball",
"createdAt": "2024-02-01T23:12:46.996Z",
"_id": "65bc256ecfb7da6997273c71",
"cards": []
},
],
卡数据
"cards": [
{
"_id": "65c43a9539206da4c953e334",
"title": "PSA 9 1996 Topps Finest Gold w/ Coating #269 Kobe Bryant Rookie Card",
"date": "2023-11-16T05:00:00.000Z",
"price": 125000,
"image": "s-l300.webp",
"search": [],
"createdAt": "2024-02-08T02:21:09.344Z",
"updatedAt": "2024-02-08T02:21:09.344Z",
"__v": 0
},
{
"_id": "65c43a9539206da4c953e32e",
"title": "1996-97 Topps Finest Bronze Refractor #74 Kobe Bryant (RC) PSA 7 W/ Coating",
"date": "2024-02-01T05:00:00.000Z",
"price": 130000,
"image": "s-l300.webp",
"search": [],
"createdAt": "2024-02-08T02:21:09.344Z",
"updatedAt": "2024-02-08T02:21:09.344Z",
"__v": 0
},
{
"_id": "65c43a9539206da4c953e332",
"title": "1996-97 Fleer Ultra Series 2 Basketball Factory Sealed Hobby Box-Kobe Bryant RC?",
"date": "2023-11-28T05:00:00.000Z",
"price": 124999,
"image": "s-l300.webp",
"search": [],
"createdAt": "2024-02-08T02:21:09.344Z",
"updatedAt": "2024-02-08T02:21:09.344Z",
"__v": 0
},
{
"_id": "65d2447cbad1f058de61ecca",
"title": "HUGE SPORTS CARD COLLECTION! 2023 CJ Stroud Justin Herbert Rookie Auto RPA READ",
"date": "2024-02-17T05:00:00.000Z",
"price": 75000,
"image": "s-l300.webp",
"search": [],
"createdAt": "2024-02-18T17:55:08.414Z",
"updatedAt": "2024-02-18T17:55:08.414Z",
"__v": 0
}
]
合计: 这段代码让我非常接近我想要的。但是,它附加结果卡数组并覆盖 catagory.cards 数组,而不是仅基于 'users.catagory.cards._id' === 'cards._id' 进行更新。
const results = await User.aggregate(
[
{
$lookup: {
from: 'cards',
localField: 'catagory.cards',
foreignField: '_id',
as: 'cards'
}
},
{
$addFields: { 'catagory.cards': '$cards' }
}
],
{ maxTimeMS: 60000, allowDiskUse: true }
);
我尝试使用过滤器,但没有成功。
{
"catagory.cards": {
$filter: {
input: "$catagory.cards",
as: "card",
cond: { $in: [ "$$card._id", "$catagory.cards"] }
}
}
}
首先很高兴看到这个问题——您到底想要实现什么。现在,让我尝试一些猜测,并告诉我是否有帮助。否则请提供更具体的期望,以便我更新答案。
我注意到的第一件事是 $lookup 中的示例中的
localField
有 'catagory.cards'
,而它应该是 'catagory.cards._id'
,因为您仅通过 _id
字段匹配,而不是整个记录。
另外,注意到一个拼写错误“类别”而不是“类别”。如果不是故意的 - 请小心,因为如果您在代码的其他部分编写 category
,这可能是某些问题的根源。
现在让我猜您想查看
category.cards
字段的数组项内的所有卡片详细信息。
可以通过以下方式实现:
$unwind
-将数组放入单独的记录中(我们必须将类别展开到单独的记录中,以便在每个记录中包含每个类别,然后展开类别卡以使每个卡在单独的记录中),$lookup
将它们与卡片详细信息匹配到 category.cards
字段(这样它将覆盖每个记录的该字段 - 这就是为什么每个类别卡都有每个记录很重要),db.User.aggregate([
{ $unwind: {
path: '$catagory',
preserveNullAndEmptyArrays: true
}},
{ $unwind: {
path: '$catagory.cards',
preserveNullAndEmptyArrays: true
}},
{ $lookup: {
from: 'cards',
localField: 'catagory.cards._id',
foreignField: '_id',
as: 'catagory.cards'
}},
{ $group: {
_id: '$catagory._id',
userId: { $first: '$_id' },
categoryId: { $first: '$catagory._id' },
name: { $first: '$catagory.name' },
createdAt: { $first: '$catagory.createdAt' },
cards: { $push: { $arrayElemAt: ['$catagory.cards', 0] } }
}},
{ $group: {
_id: '$userId',
catagory: { $addToSet: {
_id: '$categoryId',
name: '$name',
createdAt: '$createdAt',
cards: '$cards'
}},
}},
]);
我尝试了它,它为我提供了以下输出:
{
"_id" : ObjectId("65d3d362c2006d4572b028a3"),
"catagory" : [
{
"_id" : "65bc1176cfb7da6997273ae3",
"name" : "test",
"createdAt" : "2024-02-01T21:47:34.215Z",
"cards" : [
{
"_id" : "65c43a9539206da4c953e334",
"title" : "PSA 9 1996 Topps Finest Gold w/ Coating #269 Kobe Bryant Rookie Card",
"date" : "2023-11-16T05:00:00.000Z",
"price" : NumberInt(125000),
"image" : "s-l300.webp",
"search" : [
],
"createdAt" : "2024-02-08T02:21:09.344Z",
"updatedAt" : "2024-02-08T02:21:09.344Z",
"__v" : NumberInt(0)
},
{
"_id" : "65c43a9539206da4c953e32e",
"title" : "1996-97 Topps Finest Bronze Refractor #74 Kobe Bryant (RC) PSA 7 W/ Coating",
"date" : "2024-02-01T05:00:00.000Z",
"price" : NumberInt(130000),
"image" : "s-l300.webp",
"search" : [
],
"createdAt" : "2024-02-08T02:21:09.344Z",
"updatedAt" : "2024-02-08T02:21:09.344Z",
"__v" : NumberInt(0)
},
{
"_id" : "65c43a9539206da4c953e332",
"title" : "1996-97 Fleer Ultra Series 2 Basketball Factory Sealed Hobby Box-Kobe Bryant RC?",
"date" : "2023-11-28T05:00:00.000Z",
"price" : NumberInt(124999),
"image" : "s-l300.webp",
"search" : [
],
"createdAt" : "2024-02-08T02:21:09.344Z",
"updatedAt" : "2024-02-08T02:21:09.344Z",
"__v" : NumberInt(0)
},
{
"_id" : "65d2447cbad1f058de61ecca",
"title" : "HUGE SPORTS CARD COLLECTION! 2023 CJ Stroud Justin Herbert Rookie Auto RPA READ",
"date" : "2024-02-17T05:00:00.000Z",
"price" : NumberInt(75000),
"image" : "s-l300.webp",
"search" : [
],
"createdAt" : "2024-02-18T17:55:08.414Z",
"updatedAt" : "2024-02-18T17:55:08.414Z",
"__v" : NumberInt(0)
}
]
},
{
"_id" : "65bc256ecfb7da6997273c71",
"name" : "baseball",
"createdAt" : "2024-02-01T23:12:46.996Z",
"cards" : [
]
}
]
}
如果这是您想要实现的结果,如果您有任何疑问或希望获得任何进一步的说明,请告诉我。
欢迎光临!