我在搜索嵌套对象的键时遇到问题。
我有搜索条件对象,可能有也可能没有我要搜索的某些字段。
我解决这个问题的方法是使用条件语句附加到传递给聚合$ match运算符的“匹配条件”对象。它工作得很好,直到我需要匹配嵌套对象内的东西。
这是一个示例文档结构
{
name: string,
dates: {
actived: Date,
suspended: Date
},
address : [{
street: string,
city: string,
state: string,
zip: string
}]
};
我的条件对象通过UI填充并传递了一个类似于以下内容的JSON:
{
"name": "",
"state": ""
}
虽然我可以明确地使用“dates.suspended”而没有问题 - 当我尝试将address.state附加到我的搜索匹配条件时 - 我收到一个错误。
module.exports.search = function( criteria, callback )
let matchCriteria = {
"name": criteria.name,
"dates.suspended": null
};
if ( criteria.state !== '' ) {
// *** PROBLEM HAPPENS HERE *** //
matchCriteria.address.state = criteria.state;
}
User.aggregate([
{ "$match": matchCriteria },
{ "$addFields": {...} },
{ "$project": {...} }
], callback );
}
我收到错误:
TypeError:无法设置undefined的属性“state”
我知道当'地址'不存在时我正在指定'address.state' - 但我不清楚我的语法肯定不会是matchCriteria ['address.state']或“matchCriteria.address 。州”
有没有更好的方法来进行条件过滤?
要在嵌套对象中搜索,您必须使用unwind
一个帮助您的查询:
//测试声明criteria
为const
let criteria = {name : 'name', 'state' : 'state'};
let addressMatch = {};
let matchCriteria = {
"name": criteria.name,
"dates.suspended": null
};
if ( criteria.state) {
addressMatch = { 'address.state' : criteria.state };
}
db.getCollection('user').aggregate([{
$match :matchCriteria,
},{$unwind:'$address'},
{$match : addressMatch}
])
首先检查地址,然后访问该属性,如下所示:
if(matchCriteria['address']) {
matchCriteria['address']['state'] = criteria['state'];
}
else {
//otherwise
}
这应该解决它:
matchCriteria['address.state'] = criteria.state;