节点mongoose填充条件不返回预期结果

时间:2016-02-04 09:02:32

标签: javascript node.js mongodb mongoose

我正在尝试在populate方法中使用查询条件。 如果使用条件,则仍然填充所有记录,但不满足条件的记录将填充字段设置为null, 例如:

var query = BookModel.find();
query.populate('author','name',{name:'author1'});
query.find(function(err,books){
  console.log(books);
});

Then the output is:
[  { author: { _id: 4ea0db52e09aa6aad2e831fe, name: 'author1' },
    title: 'book1',
    _id: 4ea0dbebc191848704000005 },
  { author: null,
    title: 'book2',
    _id: 4ea0dbebc191848704000006 } ,
  { author: null,
    title: 'book3',
    _id: 4ea0dbebc191848704000007 } ,
  { author: null,
    title: 'book4',
    _id: 4ea0dbebc191848704000008 } ]

但是,我预计输出结果中只有第一条记录。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,我尝试了上面的代码,但它没有帮我解决问题。我找到了一种方法,就像你想要的那样。你不能使用populate来做这种过滤,你必须使用mongodb的原始查询来过滤你的数据。

// db['result'] is the name of database
db['result'].aggregate([

    // this is just like populate this populate the user field
    {
        $lookup:{
            from:'users',
            localField:'user',
            foreignField:'_id',
            as:'user'
        }
    },
    // unwind convert the array to objects to apply filter on it
    {
        $unwind:{
            preserveNullAndEmptyArrays : true, // this remove the object which is null
            path : "$user"
        }
    },
    // in match you have to define your condition this check if the user has role equals to 3
    {
        $match:{
            "user.role": 3
        }
    },
    {
        // this provide pagination
        $facet: {
            edges: [
                { $skip: sk },
                { $limit: lm },
            ],
            /* pageInfo: [
                { $group: { _id: null, count: { $sum: 1 } } },
            ],*/
        },
    }
], function (err, result) {
    if (err) {
        // this res is send if there is some error
        console.log(err);
        callback(500, err)
    } else {
        // you get the data
        console.log(result);
        callback(200, result)
    }
});

答案 1 :(得分:0)

看看这可以帮到你,我需要更多关于这个问题的信息,这是一个可能的解决方案。

 BookModel.find()
    .populate({
      path: 'author',
      match: { author: 'author1' },
      select: 'name' // I'm suppossing you want to select "name" field, if not, delete this line.
    }).find(function(err,books){
        console.log(books);
    });

或者你可以这样做:

var query = BookModel.find({name: 'author1'});
query.populate('author','name');
query.find(function(err,books){
  console.log(books);
});

答案 2 :(得分:0)

您可以在结果中添加额外的查询以过滤掉空值:

var query = BookModel.find();
query.populate('author','name',{name:'author1'});
query.find(function(err, books){
    books = books.filter(function(b){ return b.author; });
    console.log(books, null, 4);
});

控制台输出

[
    {
        "author": {
            "_id": "4ea0db52e09aa6aad2e831fe",
            "name": "author1"
        },
        "title": "book1",
        "_id": "4ea0dbebc191848704000005"
    }
]