MongoDB聚合查询$in运算符报错:传入字段不被识别为数组
MongoDB聚合查询中$in引用字段报错的解决方法
问题出在最后一个$match阶段的写法上:在普通查询条件中,$in运算符只能接收字面量数组,无法直接引用文档中的字段(比如$subscriptioncontractsIds)作为参数。必须用$expr包裹条件,使用聚合表达式来实现字段值的匹配。
修改后的最后阶段$match条件
{ '$match': { '$or': [ { 'isPremium': false }, { 'isPremium': { '$exists': false } }, { '$expr': { '$and': [ { '$eq': ['$isPremium', true] }, { '$in': ['$creatorId', '$subscriptioncontractsIds'] } ] } } ] } }
完整的聚合查询语句
[ { '$match': { 'isVisible': true, 'creatorId': new ObjectId('63ec13a4a2e93ccf1865218e') } }, { '$lookup': { 'from': 'subscriptioncontracts', 'pipeline': [ { '$match': { '$expr': { '$and': [ { '$eq': ['$userId', new ObjectId('64b7f95c9927ad922db3acc9')] }, { '$gte': ['$endDate', new Date()] }, { '$lt': ['$startDate', new Date()] } ] } } } ], 'as': 'subscriptioncontracts' } }, { '$lookup': { 'from': 'subscriptions', 'localField': 'subscriptioncontracts.subscriptionId', 'foreignField': '_id', 'as': 'subscriptioncontracts' } }, { '$addFields': { 'subscriptioncontractsIds': { '$map': { 'input': '$subscriptioncontracts', 'as': 'contract', 'in': '$$contract.creatorId' } } } }, { '$match': { '$or': [ { 'isPremium': false }, { 'isPremium': { '$exists': false } }, { '$expr': { '$and': [ { '$eq': ['$isPremium', true] }, { '$in': ['$creatorId', '$subscriptioncontractsIds'] } ] } } ] } } ]
关键说明
- 当需要在查询中引用当前文档的字段进行逻辑判断时,必须使用
$expr将聚合表达式包裹起来,这样MongoDB才会解析字段引用(如$creatorId、$subscriptioncontractsIds),而不是将其当作字符串字面量处理。 - 聚合表达式中的
$in语法与普通查询略有不同:第一个参数是要匹配的字段,第二个参数是目标数组字段。
内容的提问来源于stack exchange,提问作者Nelson Gallego
相关产品推荐
相关产品推荐

