mongodb - 查找和匹配多重集合的问题
问题描述
在多个阶段存在聚合和查找问题。问题是我无法userId
在最后一次查找中匹配。如果我省略{ $eq: ['$userId', '$$userId'] }
它,它会起作用并与其他标准匹配。但不是由userid
.
我已经尝试将添加的池作为一个让,并{ $eq: ['$userId', '$$pools.userId'] }
在最后一个阶段使用它,但这也不起作用。我得到一个空的优惠券数组。
我通过以下查询得到了这个。我想我需要以$unwind
某种方式使用?但还没有开始工作。任何指针?
共有三个集合要加入。首先是 userModel,它应该包含池,然后池应该包含用户优惠券。
{
"userId": "5df344a1372f345308dac12a", // Match this usedId with below userId coming from the coupon
"pools": [
{
"_id": "5e1ebbc6cffd4b042fc081ab",
"eventId": "id999",
"eventStartTime": "some date",
"trackName": "tracky",
"type": "foo bar",
"coupon": []
}
]
},
我需要用正确的数据(如下)填充优惠券数组,其中包含匹配的 userId。
"coupon": [
{
"eventId": "id999",
"userId": "5df344a1372f345308dac12a", // This userId need to match the above one
"checked": true,
"pool": "a pool",
}
池项目:
const poolProject = {
eventId: 1,
eventStartTime: 1,
trackName: 1,
type: 1,
};
用户项目:
const userProjection = {
_id: {
$toString: '$_id',
},
paper: 1,
correctBetsLastWeek: 1,
correctBetsTotal: 1,
totalScore: 1,
role: 1,
};
聚合查询
const result = await userModel.aggregate([
{ $project: userProjection },
{
$match: {
$or: [{ role: 'User' },
{ role: 'SuperUser' }],
},
},
{ $addFields: { userId: { $toString: '$_id' } } },
{
$lookup: {
from: 'pools',
as: 'pools',
let: { eventId: '$eventId' },
pipeline: [
{ $project: poolProject },
{
$match: {
$expr: {
$in: ['$eventId', eventIds],
},
},
},
{
$lookup: {
from: 'coupons',
as: 'coupon',
let: { innerUserId: '$$userId' },
pipeline: [
{
$match: {
$expr: {
$eq: ['$userId', '$$innerUserId'],
},
},
},
],
},
},
],
},
},
]);
感谢您的任何意见!
编辑:如果我移动第二个查找(优惠券),使它们处于相同的“级别”,它可以工作,但我希望将它放在池中。如果我添加as: 'pools.coupon'
,在最后一次查找中它会覆盖查找池数据。
解决方案
当您访问带有$$
前缀的字段时,这意味着它们被 Mongo 定义为“特殊”系统变量。
我们不确切知道 Mongo 的魔法是如何发生的,但是您用相同的名称命名了两个变量,这似乎会导致冲突。
所以要么userId: '$userId'
从第一次查找中删除,因为你甚至没有使用它。
或者重命名或第二userId: '$userId'
个不同的名称,innerUserId: '$userId'
以避免在访问时发生冲突。
只是不要忘记更改{ $eq: ['$userId', '$$userId'] }
为{ $eq: ['$userId', '$$innerUserId'] }
之后。
编辑:
现在很明显集合中没有字段userId
,pools
只需将第二个集合中的变量lookup
从以下位置更改:
let: { innerUserId: '$userId' } //userId does not exist in pools.
至:
let: { innerUserId: '$$userId' }
推荐阅读
- sql - PL/SQL 中的“使用”查询?
- linux - NASM x86_64 删除换行符并在字符串末尾添加 0
- javascript - 将整个表单 css 变灰
- c# - 从“System.String”到“Serilog.Core.IDestructuringPolicy”的无效转换
- typescript - TS2339:“窗口”类型上不存在属性“*”。仅在 WebStorm
- python - 如何使用 Python REST API 在 Azure DevOps 中检索测试结果?
- netbeans-platform - JProfiler 与 Netbeans 平台应用程序
- python - 获取需要 gtk 才能工作的旧 python 脚本
- python - 复制站点包下的包以在其他机器上使用是否安全?
- python - 除了最后几个之外,如何生成可迭代的所有值?