使用条件的Node mongoose populate未返回预期结果。

3

我正在尝试在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个回答

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

$lookup总是从连接的集合返回一个数组。$unwind用于转换为对象。然后我们可以使用$match编写条件,这也会影响父节点。希望这有所帮助。 - murtuza hussain

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

仍然是相同的结果。 - user233232

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"
    }
]

这是一个简单的JS解决方案,在Mongo中没有内置的解决方案吗? - user233232

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接