Mongoose Populate返回一些空对象

时间:2016-12-23 18:38:31

标签: node.js mongodb mongoose

我有1个主要集合和1个集合,其中包含对主要集合的引用。代码如下:

// Ref schema
    const onlineSchema = mongoose.Schema({
        _id: {
            type: Number,
            ref: 'Player',
            unique: true
        }
    }, {
        timestamps: true
    });

//main schema

const playerSchema = mongoose.Schema({

_id: { // User ID
    type: Number,
    required: true,
    unique: true,
    default: 0
},
firstname: {
    type: String
},
name: {
    type: String,
    required: true
},
lastname: {
    type: String
},
barfoo: {
   type: Boolean
}
...

})

我用这段代码填充它:

var baz = bar;
...
        Online.find().populate({
            path: '_id',
            match: {
                [ baz + 'foo']: true
            }
        }).exec(function(err, online) {
            if (err) {
                winston.error(err);
            } else {
                winston.error(util.inspect(online, {
                    showHidden: false,
                    depth: null
                }));

            }
        });

如果在线有10个元素且只有7个匹配[ baz + 'foo']: true,我会得到7个正确的数组和3个空数组,如下所示:

    { updatedAt: 2016-12-23T18:00:32.725Z,
createdAt: 2016-12-23T18:00:32.725Z,
_id: null,
 __v: 0 },

为什么会发生这种情况以及如何过滤最终结果以便它只显示匹配的元素?

我可以在获得结果后使用过滤器来删除空数组,但我想知道如何防止查询首先传递空数组。

3 个答案:

答案 0 :(得分:1)

  

为什么会这样?

这种情况正在发生,因为您获得了Online.find()的所有文档,但只会为符合条件的记录填充player。您的match适用于populate,不适用于find()查询。

  

如何过滤最终结果,以便仅显示匹配项   元素?

由于MongoDB中没有连接,因此无法找到引用集合的嵌套元素。但你可以:

  • 保留您的架构并使用$lookup聚合:

    Online.aggregate(
        [{
            $lookup: {
                from: "players",
                localField: "_id",
                foreignField: "_id",
                as: "players"
            }
        }, {
            $unwind: "$players"
        }, {
            $match: {
                'players.barfoo': true
            }
        }],
        function(err, result) {
            console.log(result);
        });
    
  • 更改架构以包含Player作为子文档:

    const playerSchema = new mongoose.Schema({
        //...
    });
    
    const onlineSchema = new mongoose.Schema({
        player: playerSchema
    }, {
        timestamps: true
    });
    
    var Online = mongoose.model('Online', onlineSchema);
    
    Online.find({'player.barfoo':true}).exec(function(err, online) {
        console.log(online);
    });
    

答案 1 :(得分:0)

不要将_id设置为另一个架构的reference,而是创建另一个field名称player并通过该reference提供。{/ p>

const onlineSchema = mongoose.Schema({
    player: {
        type: Number,
        ref: 'Player',
        unique: true
    }
}, {
    timestamps: true
});

人口:

Online.find().populate({
    path: 'player',
    match: {
        [ baz + 'foo']: true
    }
}).exec(...);

答案 2 :(得分:0)

不要使用_id来引用字段..因为它在mongoDB中默认存档以创建唯一的索引..更改你的字段名称