MongoDB $lookup 管道匹配 _id 不起作用 [英] MongoDB $lookup pipeline match by _id not working
问题描述
我正在尝试在集合中执行 $lookup
并向我的文档添加一些数据.问题是,当我尝试通过 _id
匹配我的 $lookup
管道时,它返回一个空数组.这是我的代码:
i'm trying to do a $lookup
in a collection and add some data to my documents. The problem is that when i try matching my $lookup
pipeline by _id
it returns an empty array. Here is my code:
Schedule.aggregate([{ // My Schedule schema
$match: {
store: req.query.store,
"customer.id": req.query.user
}
},
{
$skip: +req.query.skip
}, {
$limit: +req.query.limit
},
{
$lookup: {
from: Employee.collection.name, // "employee" schema,
let: {
id: "$employee.id" // employee _id from the "schedule" collection match above
},
pipeline: [{
$match: {
$expr: {
"_id": "$$id" // here i try to match by _id
}
}
},
{
$project: { // the only fields i need
"_id": 1,
"avatar": 1,
"name": 1
}
}
],
as: "employees" // employees is returned as []
}
}
]).exec((err, resolve) => {
if (err) console.log('error', err);
res.json(resolve);
});
如果有帮助,这里是我在此聚合中使用的两个集合:
If it helps here's both my collections used in this aggregation:
计划架构:
const ScheduleSchema = new Schema({
store: {
type: String,
required: true
},
customer: {
id: {
type: String
},
name: {
type: String
},
avatar: String,
phone: {
type: String
},
email: { type: String },
doc: {
type: String
},
},
employee: {
id: {
type: mongoose.Schema.Types.ObjectId,
required: true
},
name: {
type: String,
required: true
},
avatar: String,
},
service: {
id: {
type: String
},
name: {
type: String,
required: true
},
filters: [String]
},
info: {
channel: {
type: String,
required: true,
default: 'app'
},
id: mongoose.Schema.Types.ObjectId,
name: String
},
scheduleDate: {
type: String,
required: true
},
scheduleStart: {
type: String,
required: true
},
scheduleEnd: {
type: String,
required: true
},
value: {
type: Number
},
comissionType: {
type: String,
default: '$'
},
comissionValue: {
type: Number,
default: 0
},
status: {
type: Number,
required: true
},
observation: String,
paymentMethod: {
type: Number,
default: 0
},
paymentValue: String,
paymentChange: String,
color: String
}, {
timestamps: {
createdAt: 'created',
updatedAt: 'updated'
}
});
员工架构:
const EmployeeSchema = new Schema({
name: {
type: String,
required: true
},
a_to_z: String, // nome normalizado, só minusculas e sem espaços
description: String,
email: {
type: String,
required: true
},
avatar: String,
phone: {
type: String
},
storeOwner: {
type: Boolean,
required: true
},
permissions: [
{
route: String,
hasPermission: Boolean
}
],
scheduleAutomatic: {
type: Boolean,
required: true,
default: false
},
password: {
passwordHash: String,
salt: String
},
active: {
type: Boolean,
default: true
},
storeKey: {
type: String,
required: true
},
notification_token: String,
notification_tokens: {
type: [String],
default: []
},
workingHours: [{
weekDay: {
type: Number,
},
doesWork: {
type: Boolean,
},
startHour: String,
endHour: String,
lunchStart: String,
lunchEnd: String
}],
config: {
available_days: {
type: Number,
default: 365
},
in_advance_schedule: {
type: Number,
default: 0
},
in_advance_interval: {
type: String,
default: 'minute'
}
}
}, {
timestamps: {
createdAt: 'created',
updatedAt: 'updated'
}
});
编辑
我想要达到的结果是:
EDIT
The result i'm trying to achieve is this:
employees
属性是我尝试使用 $lookup
获取的属性,它将与 employee
具有相同的数据> 属性,最终它会是一个对象数组,里面只有一个对象.
The employees
property is the one i'm trying to use $lookup
to get, it'll have the same data as the employee
property, in the end it'll be and array of objects with just one object inside.
一些示例文档:
时间表:
color: "lavander",
created: "2018-07-31T18:50:53.423Z",
customer: {id: "5b60a67206e8a65f48a15f13", name: "Gabriel Barreto", phone: "11995274098", cpf: "40735255814"},
employee: {id: "5b2952c68424872fccece7f5", name: "Gabriel Barreto", avatar: null},
observation: "teste",
scheduleDate: "2018-08-01",
scheduleEnd: "2018-08-01 08:30",
scheduleStart: "2018-08-01 08:00",
service: {filters: Array(3), id: "5b606e8cc59e82354cc931e2", name: "Corte Masc"},
status: 1,
store: "5b16cceb56a44e2f6cd0324b",
updated: "2018-11-27T13:27:40.310Z",
value: 25,
__v: 0,
_id: "5b60af8de558661acc5d70b9"
员工:
a_to_z: "gabrielbarreto",
active: true,
avatar: "gabriel_barreto_h7qvcn.jpg",
config: {available_days: 180, in_advance_schedule: 10, in_advance_interval: "hour"},
created: "2018-06-19T19:00:22.315Z",
currency: "BRL",
description: "Novo perfil",
email: "gabriel.barreto@wabiz.com.br",
lang: "pt-BR",
name: "Gabriel Barreto",
notification_token: "2d768670-6011-4873-846d-39580b0d82d0",
notification_tokens: ["53049a82-53dc-4bc3-9646-7a4bee1f367b"],
password: null,
permissions: (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}],
phone: "11995274098",
scheduleAutomatic: false,
storeKey: "5b16cceb56a44e2f6cd0324b",
storeOwner: true,
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImdhYnJpZWwuYmFycmV0b0B3YWJpei5jb20uYnIiLCJpYXQiOjE1NTA2NzEwNDQsImV4cCI6MTU1MzI2MzA0NH0.0Odizd8pS4WPGSqm_2_XrTw1YE8NMOOXnHIrG-WVxGo",
updated: "2019-02-20T13:34:20.619Z",
workingHours: (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}],
__v: 0,
_id: "5b2952c68424872fccece7f5"
感谢您的时间
推荐答案
我在使用 $lookup 和 mongoose 尝试匹配 _id 时也遇到了麻烦,因为我的集合将引用存储为 String 而不是 ObjectId
I was in trouble too while using $lookup with mongoose to trying to match _id as my collection store the reference as a String and not an ObjectId
模型 A:{_id: ObjectId("xxx"), b_id: "eeeee"}
Model A: {_id: ObjectId("xxx"), b_id: "eeeee"}
模型 B:{_id: ObjectId("eeeee")}
Model B: {_id: ObjectId("eeeee")}
MyCollectionA.aggregate([
{
$lookup: {
from: "collectionb",
let: {id: "$b_id"},
pipeline: [{$match: {$expr: {$eq: ["$_id", "$$id"]}}}],
as: b
}
])
在这个例子中,b 永远不会被填充,因为 $$id 不被认为是一个 ObjectId
In this example b is never filled as $$id is not considered as an ObjectId
只需添加一个项目来转换 objectId 中的 $$id 及其工作
Just add a project to transform $$id in an objectId and its working
MyCollectionA.aggregate([
{
$lookup: {
from: "collectionb",
let: {id: "$b_id"},
pipeline: [
{$project: {_id: 1, bid: {"$toObjectId": "$$id"}}},
{$match: {$expr: {$eq: ["$_id", "$bid"]}}}
],
as: b
}
])
或者使用foreignField、localField:
Or with foreignField, localField:
MyCollectionA.aggregate([
{
$project:{
_id: 1,
b_id: {"$toObjectId": "$b_id"}
}
},
{
$lookup: {
from: "collectionb",
localField: "b_id",
foreignField: "_id",
as: b
}
])
这篇关于MongoDB $lookup 管道匹配 _id 不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!