使用猫鼬填充数据过滤

时间:2019-08-14 15:05:39

标签: javascript node.js mongodb mongoose relationship

我有两个数据结构“数据库”和“组件”

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,
});

我想按组件名称过滤数据库中的所有项目

我正在使用的搜索规则

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);
});

但是总是返回一个空元素

1 个答案:

答案 0 :(得分:0)

请尝试:

正如我已经建议您可以使用的那样:

Database.find({})
    .populate({ path: 'components', match: { name: /antr/i }, select: 'name -_id' })
    .exec((err, data) => { console.log(err); res.json(data); });

由于您看到的是空数组,是由于match中的过滤器查询未在组件集合中找到合适的文档。数据库文件的components数组中的ObjectIds,这是正常的。也许您可以用代码过滤掉这些内容,因为您不是那种样子,您可以在聚合框架中使用mongoDB的$lookup,相当于在mongoose中使用.populate()

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' } }])

集合中的数据示例:

组件:

/* 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
}

数据库:

/* 1 */
{
    "_id" : ObjectId("5d4979d52a17d10a6c8de81b"),
    "components" : [ 
        ObjectId("5d481cd098ba991c0857951f"), 
        ObjectId("5d481cd098ba991c0857952f"), 
        ObjectId("5d481cd098ba991c0857953f"), 
        ObjectId("5d481cd098ba991c0857959f")
    ]
}

输出:

/* 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
        }
    ]
}