简体   繁体   English

有条件的猫鼬

[英]Mongoose Populate with a condition

in a Node.js App with Mongoose(Mongodb) , With this code i fetch users and their books: 在带有Mongoose(Mongodb)Node.js应用程序中,通过此代码,我可以获取用户及其书籍:

Users.find({user_id: req.user.id}).populate('books').exec(..);

Right now i want to fetch users that has an special book. 现在,我想获取有一本特殊书籍的用户。 i do like this: 我喜欢这样:

Users.find({user_id: req.user.id}).populate('books',null,{bookname:"harry potter"}).exec(..);

But it doesn't work. 但这是行不通的。 With this, my code fetches users with their books of null value and if that condition matches, return them instead of null. 有了这个,我的代码便用null值的书来获取用户,如果该条件匹配,则返回他们而不是空值。 In fact most of my users has null value for books. 其实我大部分的用户都有null了图书的价值。 but what i want is that if that condioton in populate section is not matches, do not return that user in result array at all! 但是我想要的是,如果填充部分中的该条件不匹配,则根本不要在结果数组中返回该用户!

What i have to do? 我该怎么办? i have to do another query or something on results for what i need? 我必须做另一个查询或对我需要的结果做些什么?

All I can think here is that you are calling it wrong. 我能想到的就是你在说错了。 You do not really show much context here other than that your .populate() parameters do not look correct. 除了.populate()参数看起来不正确之外,您.populate()在此处显示太多上下文。

Here is a correct listing as a reproducible example: 这是一个正确的清单,作为可重复的示例:

var async = require('async'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var thingSchema = new Schema({
  _id: Number,
  name: String
},{ _id: false });

var parentSchema = new Schema({
  name: String,
  things: [{ type: Number, ref: 'Thing' }]
});

var Thing = mongoose.model( 'Thing', thingSchema ),
    Parent = mongoose.model( 'Parent', parentSchema );

mongoose.connect('mongodb://localhost/thingtest');

var things = { "one": 1, "two": 2, "three": 3 };

async.series(
  [
    function(callback) {
      async.each([Thing,Parent],function(model,callback) {
        model.remove({},callback);
      },callback);
    },
    function(callback) {
      var parentObj = new Parent({ "name": "me" });
      async.each(
        Object.keys(things).map(function(key) {
          return { "name": key, "_id": things[key] }
        }),
        function(thing,callback) {
          var mything = new Thing(thing);
          parentObj.things.push(thing._id)
          mything.save(callback)
        },
        function(err) {
          if (err) callback(err);
          parentObj.save(callback);
        }
      );
    },
    function(callback) {
      console.log("filtered");
      var options = {
        path: 'things',
        match: { "name": { "$in": ['two','three'] } }
      };

      Parent.find().populate(options).exec(function(err,docs) {
        if (err) callback(err);
        console.log(docs);
        callback();
      });
    },
    function(callback) {
      console.log('unfiltered');
      Parent.find().populate('things').exec(function(err,docs) {
        if (err) callback(err);
        console.log(docs);
        callback();
      })
    }
  ],
  function(err) {
    if (err) throw err;
    mongoose.disconnect();
  }
);

Which will consistently give results like this: 这将始终给出如下结果:

filtered
[ { _id: 55ec4c79f30f550939227dfb,
    name: 'me',
    __v: 0,
    things:
     [ { _id: 2, name: 'two', __v: 0 },
       { _id: 3, name: 'three', __v: 0 } ] } ]
unfiltered
[ { _id: 55ec4c79f30f550939227dfb,
    name: 'me',
    __v: 0,
    things:
     [ { _id: 1, name: 'one', __v: 0 },
       { _id: 2, name: 'two', __v: 0 },
       { _id: 3, name: 'three', __v: 0 } ] } ]

So take a good look at your data and your calls. 因此,请仔细查看您的数据和通话。 The .populate() call needs to match the "path" and then also provide a "match" to query the documents that are to be populated. .populate()调用需要匹配“路径”,然后还提供“匹配”以查询要填充的文档。

Use elemMatch: 使用elemMatch:

var title = 'Harry Potter';
Users.find({books: {$elemMatch: {name: title}})
.exec(processResults);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM