MongoDb:管道内部查找错误:错误:参数必须是聚合管道运算符
Posted
技术标签:
【中文标题】MongoDb:管道内部查找错误:错误:参数必须是聚合管道运算符【英文标题】:MongoDb: Pipeline inside lookup error: Error: Arguments must be aggregate pipeline operators 【发布时间】:2021-06-12 11:48:37 【问题描述】:我有这三个模型:
Institution
模特:
const InstitutionSchema = new Schema(
current_students: [
type: Schema.Types.ObjectId,
ref: "users",
,
],
);
module.exports = Institution = mongoose.model("institutions", InstitutionSchema);
在current_students
字段中有对User
模型的引用数组。
User
模特:
const UserSchema = new Schema(
profile:
type: Schema.Types.ObjectId,
ref: "profiles",
,
);
module.exports = User = mongoose.model("users", UserSchema);
在profile
字段中引用了Profile
模型。
Profile
模特:
const ProfileSchema = new Schema(
videoURL:
type: String,
,
);
module.exports = Profile = mongoose.model("profiles", ProfileSchema);
我正在尝试获取Profile.videoURL
不是null
或undefined
的机构用户的配置文件列表。这是我尝试过的:
Institution.aggregate([
$lookup:
from: "users",
localField: "current_students",
foreignField: "_id",
as: "current_student",
,
,
$unwind:
path: "$current_student",
preserveNullAndEmptyArrays: true,
,
,
$lookup:
from: "profiles",
localField: "current_student.profile",
foreignField: "_id",
as: "current_student_profile",
,
pipeline: [
$match:
videoURL: $nin: [undefined, null] ,
,
,
],
,
]);
但是,由于执行$match
操作的最后一个管道,我不断收到此错误。
Error: Arguments must be aggregate pipeline operators
知道如何解决这个问题吗?
【问题讨论】:
【参考方案1】:您的查询是错误的。你不能像那样通过pipeline
。看看$lookup
语法。另外,如果您想了解有关聚合的更多信息,我建议您使用 MongoDB 自己提供的 Aggregation course。对所有人免费。
试试这个查询:
db.institutions.aggregate([
$lookup:
from: "users",
localField: "current_students",
foreignField: "_id",
as: "current_student",
,
$unwind:
path: "$current_student",
preserveNullAndEmptyArrays: true,
,
$lookup:
from: "profiles",
localField: "current_student.profile",
foreignField: "_id",
as: "current_student_profile",
,
$unwind: "$current_student_profile" ,
$match:
"current_student_profile.videoURL": $nin: [undefined, null] ,
]);
输出:
/* 1 createdAt:3/13/2021, 6:18:26 PM*/
"_id" : ObjectId("604cb49a6b2dcb17e8b152b2"),
"name" : "Institute 1",
"current_students" : [
ObjectId("604cb4c36b2dcb17e8b152b8"),
ObjectId("604cb4c36b2dcb17e8b152b9")
],
"current_student" :
"_id" : ObjectId("604cb4c36b2dcb17e8b152b8"),
"name" : "Dheemanth Bhat",
"profile" : ObjectId("604cb4b16b2dcb17e8b152b5")
,
"current_student_profile" :
"_id" : ObjectId("604cb4b16b2dcb17e8b152b5"),
"videoURL" : "http://abc1@xyz.com"
,
/* 2 createdAt:3/13/2021, 6:18:26 PM*/
"_id" : ObjectId("604cb49a6b2dcb17e8b152b3"),
"name" : "Institute 2",
"current_students" : [
ObjectId("604cb4c36b2dcb17e8b152ba")
],
"current_student" :
"_id" : ObjectId("604cb4c36b2dcb17e8b152ba"),
"name" : "Alex Rider",
"profile" : ObjectId("604cb4b16b2dcb17e8b152b7")
,
"current_student_profile" :
"_id" : ObjectId("604cb4b16b2dcb17e8b152b7"),
"videoURL" : "http://abc3@xyz.com"
测试数据:
users
收藏:
/* 1 createdAt:3/13/2021, 6:19:07 PM*/
"_id" : ObjectId("604cb4c36b2dcb17e8b152b8"),
"name" : "Dheemanth Bhat",
"profile" : ObjectId("604cb4b16b2dcb17e8b152b5")
,
/* 2 createdAt:3/13/2021, 6:19:07 PM*/
"_id" : ObjectId("604cb4c36b2dcb17e8b152b9"),
"name" : "Ahmed Ghrib",
"profile" : ObjectId("604cb4b16b2dcb17e8b152b6")
,
/* 3 createdAt:3/13/2021, 6:19:07 PM*/
"_id" : ObjectId("604cb4c36b2dcb17e8b152ba"),
"name" : "Alex Rider",
"profile" : ObjectId("604cb4b16b2dcb17e8b152b7")
profiles
收藏:
/* 1 createdAt:3/13/2021, 6:18:49 PM*/
"_id" : ObjectId("604cb4b16b2dcb17e8b152b5"),
"videoURL" : "http://abc1@xyz.com"
,
/* 2 createdAt:3/13/2021, 6:18:49 PM*/
"_id" : ObjectId("604cb4b16b2dcb17e8b152b6")
,
/* 3 createdAt:3/13/2021, 6:18:49 PM*/
"_id" : ObjectId("604cb4b16b2dcb17e8b152b7"),
"videoURL" : "http://abc3@xyz.com"
institutions
收藏
/* 1 createdAt:3/13/2021, 6:18:26 PM*/
"_id" : ObjectId("604cb49a6b2dcb17e8b152b2"),
"name" : "Institute 1",
"current_students" : [
ObjectId("604cb4c36b2dcb17e8b152b8"),
ObjectId("604cb4c36b2dcb17e8b152b9")
]
,
/* 2 createdAt:3/13/2021, 6:18:26 PM*/
"_id" : ObjectId("604cb49a6b2dcb17e8b152b3"),
"name" : "Institute 2",
"current_students" : [
ObjectId("604cb4c36b2dcb17e8b152ba")
]
【讨论】:
【参考方案2】:必须是这样的:
Institution.aggregate([
$lookup:
from: "users",
localField: "current_students",
foreignField: "_id",
as: "current_student",
,
,
$unwind:
path: "$current_student",
preserveNullAndEmptyArrays: true,
,
,
$lookup:
from: "profiles",
localField: "current_student.profile",
foreignField: "_id",
as: "current_student_profile",
,
$match:
videoURL: $nin: [undefined, null] ,
,
]);
注意,这看起来像是关系 RDBMS 设计的“一对一”转换。通常它不是将每个表格转换为集合的最佳方法,通常集合应该有不同的设计。
【讨论】:
这将返回一个空数组。我认为这是有道理的,因为 videoURL 是 Profile 模型中的字段,而不是机构模型中的字段。因此,正如您编写的那样,它检查的是 Institution.videoURL 而不是 Profile.videoURL,因此它始终是未定义的,并且返回的结果是一个空数组。以上是关于MongoDb:管道内部查找错误:错误:参数必须是聚合管道运算符的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB 聚合错误:管道阶段规范对象必须只包含一个字段
Scikit-learn 管道类型错误:zip 参数 #2 必须支持迭代
java spring 中使用 AggregationOperation 的 Mongodb 内部连接:错误 [需要'cursor' 选项,但带有解释参数的聚合除外]