预先查找查询

时间:2017-08-24 15:06:51

标签: node.js mongodb express mongoose mongoose-schema

我有以下问题。我有一些软删除的评论。因此,他们有一个标志is_deleted,并在删除记录时设置为true。

我的评论不是一个独立的模型,但它们是另一个模型中的嵌套数组(简化模型):

let CommentSchema = new Schema({
    text: {
        type: String,
        required: true
    },
    modified_at: {
        type: Date,
        default: null
    },
    created_at: {
        type: Date,
        default: Date.now
    },
    is_deleted: {
        type: Boolean,
        default: false
    },
});

let BookSchema = new Schema({
    ...
    comments: [CommentSchema],
    ...
});

现在,当我使用Books.find({}, (err, books) => {})获取所有图书时,我想过滤掉已删除的评论:

BookSchema.pre('find', function() {
    this.aggregate(
    {},
    { $unwind: '$comments'},
    { $match: {'comments.is_deleted': false}})
}); 

但它不起作用。知道如何编写查询,以便它只返回未删除的嵌套注释而不创建独立的Comment集合吗?

编辑:我没有提到它是一个我只能访问一个图书对象的端点。资源网址如下:/books/{bookId}/comments。但是如果它能在获取所有书籍对象时起作用,那也很好。

1 个答案:

答案 0 :(得分:1)

您可以直接使用positional $ operator和过滤器查找。正如@Blakes Seven Here

所阐述的那样
BookSchema.find({
 'comments.is_deleted': false,
}, {
 'comments.$': 1,
});

修改

正如你所说,$ operator只返回一个元素,这就是文档所说的内容:

  

位置$运算符限制了a的内容   查询结果只包含与查询匹配的第一个元素   文件

您的问题有两种解决方案:

  1. 制作一个聚合,通常由数据库执行很慢
  2. 获取图书并使用循环过滤评论
  3. BookSchema.find({
       'comments.is_deleted': false,
    }).map(x => Object.assign(x, {
       comments: x.comments.filter(y => !y.is_deleted),
    }));
    

    find获取所有未删除评论的图书。

    每本书上的地图循环。

    然后我们删除标记为已删除的评论