如何从 Mongoose 填充查询中排除空值
How to exclude null values from Mongoose populate query
我正在构建一个应用程序,我已经创建了 2 个模型。
const UserSchema = new Schema({
_id: Schema.Types.ObjectId,
account:{
type: String,
unique: true
},
email: String,
first_name: String,
last_name: String
}
const VenueSchema = new Schema({
_id: Schema.Types.ObjectId,
venue_type: String,
capacity: Number
})
和
const MediatorSchema = new Schema({
_id: Schema.Types.ObjectId,
account:{
type: String,
unique: true
},
user: {type: Schema.Types.ObjectId,
ref:'User'
}
venue: {type: Schema.Types.ObjectId,
ref:'Venue'
}
})
创建调解器架构是为了填充多个路径。
问题是当我尝试创建类似
的查询时
var populateQuery = [{path:'user',match: { account:'testuser1'},select:'email'},{path:'venue',match: { venue_type: 'club'}, select:'venue_type'}];
const confirmedVenues = await Mediator.find({})
.exists('venue',true)
.populate(populateQuery)
.exec();
当匹配不成立时,返回的数组包含具有空值的对象。
例如,当我查询之前的匹配项时,我得到以下结果
所以我想要的是,当用户或场所或某物为 NULL(因此匹配未实现)时,不返回 Whole 对象。
我得到了以下解决方案,但我不想这样做
var i =confirmedVenues.length;
while(i--){
if(confirmedVenues[i].user == null){
temp.splice(i,1)
}
}
最后,我不得不在这里使用聚合,没有其他选择。
架构不需要更改
var results =await dbo.collection('mediators').aggregate([
{ $lookup:
{
from: 'venues',
localField: 'venue',
foreignField: '_id',
as: 'venue'
}
},
$match:{$and:[{"venue.venue_type":req.query.venue_type} , {"venue.capacity":{$gte:parseInt(req.query.capacitylb) , $lte:parseInt(req.query.capacityub)}}]}
},{
$lookup:
{
from: 'users',
localField: 'user',
foreignField: '_id',
as: 'user'
}
},{
$lookup:
{
from: 'professionals',
localField: 'professional',
foreignField: '_id',
as: 'professional'
}
},{
$lookup:
{
from:'availabilities',
localField: 'availability',
foreignField: '_id',
as: 'availability'
}
},{
$unwind: '$availability'
},{
$match:{$and:[{"availability.start":{$lte:new Date(req.query.dateFrom)}},{"availability.end":{$gte:new Date(req.query.dateTo)}}]}
},{
$lookup:
{
from:'locations',
localField: 'location',
foreignField: '_id',
as: 'location'
}
},{
$project:{
"_id":1,
"email":"$user.email",
"organization_name":"$user.organization_name",
"website":"$user.website",
"profile_pic_hash":"$user.profile_pic_hash",
"bio_hash":"$user.bio_hash",
"venue_type":"$venue.venue_type",
"capacity":"$venue.capacity",
"flat_fee":"$professional.flat_fee",
"per_participant_fee":"$professional.per_participant_fee",
"hourly_fee":"$professional.hourly_fee",
"start_date":"$availability.start",
"end_date":"$availability.end",
"distance":"$dist.calculated",
"location":"$location.location.coordinates",
"country":"$location.country",
"city":"$location.city",
"street":"$location.street",
"number":"$location.number",
"zip":"$location.zip"}}
它非常适合我。感谢 Anthony Winzlet 的帮助。
我正在构建一个应用程序,我已经创建了 2 个模型。
const UserSchema = new Schema({
_id: Schema.Types.ObjectId,
account:{
type: String,
unique: true
},
email: String,
first_name: String,
last_name: String
}
const VenueSchema = new Schema({
_id: Schema.Types.ObjectId,
venue_type: String,
capacity: Number
})
和
const MediatorSchema = new Schema({
_id: Schema.Types.ObjectId,
account:{
type: String,
unique: true
},
user: {type: Schema.Types.ObjectId,
ref:'User'
}
venue: {type: Schema.Types.ObjectId,
ref:'Venue'
}
})
创建调解器架构是为了填充多个路径。
问题是当我尝试创建类似
的查询时var populateQuery = [{path:'user',match: { account:'testuser1'},select:'email'},{path:'venue',match: { venue_type: 'club'}, select:'venue_type'}];
const confirmedVenues = await Mediator.find({})
.exists('venue',true)
.populate(populateQuery)
.exec();
当匹配不成立时,返回的数组包含具有空值的对象。
例如,当我查询之前的匹配项时,我得到以下结果
所以我想要的是,当用户或场所或某物为 NULL(因此匹配未实现)时,不返回 Whole 对象。
我得到了以下解决方案,但我不想这样做
var i =confirmedVenues.length;
while(i--){
if(confirmedVenues[i].user == null){
temp.splice(i,1)
}
}
最后,我不得不在这里使用聚合,没有其他选择。
架构不需要更改
var results =await dbo.collection('mediators').aggregate([
{ $lookup:
{
from: 'venues',
localField: 'venue',
foreignField: '_id',
as: 'venue'
}
},
$match:{$and:[{"venue.venue_type":req.query.venue_type} , {"venue.capacity":{$gte:parseInt(req.query.capacitylb) , $lte:parseInt(req.query.capacityub)}}]}
},{
$lookup:
{
from: 'users',
localField: 'user',
foreignField: '_id',
as: 'user'
}
},{
$lookup:
{
from: 'professionals',
localField: 'professional',
foreignField: '_id',
as: 'professional'
}
},{
$lookup:
{
from:'availabilities',
localField: 'availability',
foreignField: '_id',
as: 'availability'
}
},{
$unwind: '$availability'
},{
$match:{$and:[{"availability.start":{$lte:new Date(req.query.dateFrom)}},{"availability.end":{$gte:new Date(req.query.dateTo)}}]}
},{
$lookup:
{
from:'locations',
localField: 'location',
foreignField: '_id',
as: 'location'
}
},{
$project:{
"_id":1,
"email":"$user.email",
"organization_name":"$user.organization_name",
"website":"$user.website",
"profile_pic_hash":"$user.profile_pic_hash",
"bio_hash":"$user.bio_hash",
"venue_type":"$venue.venue_type",
"capacity":"$venue.capacity",
"flat_fee":"$professional.flat_fee",
"per_participant_fee":"$professional.per_participant_fee",
"hourly_fee":"$professional.hourly_fee",
"start_date":"$availability.start",
"end_date":"$availability.end",
"distance":"$dist.calculated",
"location":"$location.location.coordinates",
"country":"$location.country",
"city":"$location.city",
"street":"$location.street",
"number":"$location.number",
"zip":"$location.zip"}}
它非常适合我。感谢 Anthony Winzlet 的帮助。