问题
I have two data structures "database" and "components"
const DatabaseSchema = mongoose.Schema({
components: [{ type: Schema.Types.ObjectId, ref: 'Components', required: false }],
});
const ComponentsSchema = mongoose.Schema({
name: { type: String, required: true, trim: true, unique: true, lowercase: true },
updatedAt: Date,
});
I want to filter all items in the database by component names
search rule I'm using
Database.find({
components: { $elemMatch: { name: /antr/i } }
}).populate({
path: 'components',
select: 'name -_id'
}).select(['descript','components']).exec( (err,data) => {
console.log(err);
res.json(data);
});
however always return an empty element
回答1:
Please try this :
As I've already suggested you can use this :
Database.find({})
.populate({ path: 'components', match: { name: /antr/i }, select: 'name -_id' })
.exec((err, data) => { console.log(err); res.json(data); });
Since you're seeing empty array's is because of the filter query in match
which doesn't find appropriate documents in components collection w.r.t. ObjectIds in components array of database document, this is normal. May be you can filter those out in code, as you aren't looking in that way, You can use mongoDB's $lookup
from aggregation framework which is equivalent to .populate()
from mongoose.
Database.aggregate(
[{
$lookup: {
from: "components",
"let": { "ids": "$components" },
pipeline: [
{ $match: { $expr: { $in: ['$_id', '$$ids'] } } }],
as: "dbComponentsArray"
}
}, { $unwind: '$dbComponentsArray' }, { $match: { 'dbComponentsArray.name': /antr/i } },
{ $group: { _id: '$_id', dbComponentsArray: { $push: '$dbComponentsArray' }, data: { $first: '$$ROOT' } } }, { $addFields: { 'data.dbComponentsArray': '$dbComponentsArray' } },
{ $replaceRoot: { 'newRoot': '$data' } }])
Sample Data in collections :
components :
/* 1 */
{
"_id" : ObjectId("5d481cd098ba991c0857959f"),
"name" : "antracito",
"updatedAt" : ISODate("2019-08-05T12:10:56.777Z"),
"__v" : 0
}
/* 2 */
{
"_id" : ObjectId("5d481cd098ba991c0857958f"),
"name" : "anacito",
"updatedAt" : ISODate("2019-08-05T12:10:56.777Z"),
"__v" : 0
}
/* 3 */
{
"_id" : ObjectId("5d481cd098ba991c0857951f"),
"name" : "antracito",
"updatedAt" : ISODate("2019-08-05T12:10:56.777Z"),
"__v" : 0
}
/* 4 */
{
"_id" : ObjectId("5d481cd098ba991c0857952f"),
"name" : "anacito",
"updatedAt" : ISODate("2019-08-05T12:10:56.777Z"),
"__v" : 0
}
database :
/* 1 */
{
"_id" : ObjectId("5d4979d52a17d10a6c8de81b"),
"components" : [
ObjectId("5d481cd098ba991c0857951f"),
ObjectId("5d481cd098ba991c0857952f"),
ObjectId("5d481cd098ba991c0857953f"),
ObjectId("5d481cd098ba991c0857959f")
]
}
Output :
/* 1 */
{
"_id" : ObjectId("5d4979d52a17d10a6c8de81b"),
"components" : [
ObjectId("5d481cd098ba991c0857951f"),
ObjectId("5d481cd098ba991c0857952f"),
ObjectId("5d481cd098ba991c0857953f"),
ObjectId("5d481cd098ba991c0857959f")
],
"dbComponentsArray" : [
{
"_id" : ObjectId("5d481cd098ba991c0857959f"),
"name" : "antracito",
"updatedAt" : ISODate("2019-08-05T12:10:56.777Z"),
"__v" : 0
},
{
"_id" : ObjectId("5d481cd098ba991c0857951f"),
"name" : "antracito",
"updatedAt" : ISODate("2019-08-05T12:10:56.777Z"),
"__v" : 0
}
]
}
来源:https://stackoverflow.com/questions/57497393/filter-data-using-mongoose-populate