Javascript 猫鼬以一种状态繁殖

Javascript 猫鼬以一种状态繁殖,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,在带有Mongoose(Mongodb)的Node.js应用程序中,我使用此代码获取用户及其书籍: Users.find({user_id: req.user.id}).populate('books').exec(..); 现在,我想获取拥有一本特别书籍的用户。我喜欢这样: Users.find({user_id: req.user.id}).populate('books',null,{bookname:"harry potter"}).exec(..); filtered [ { _i

在带有
Mongoose(Mongodb)
Node.js
应用程序中,我使用此代码获取用户及其书籍:

Users.find({user_id: req.user.id}).populate('books').exec(..);
现在,我想获取拥有一本特别书籍的用户。我喜欢这样:

Users.find({user_id: req.user.id}).populate('books',null,{bookname:"harry potter"}).exec(..);
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 } ] } ]
但它不起作用。这样,我的代码会获取用户的
null
值,如果该条件匹配,则返回它们而不是null。事实上,我的大多数用户对书籍都有
null
值。但我想要的是,如果填充部分中的condioton不匹配,则根本不要在结果数组中返回该用户

我该怎么办?我需要对结果执行另一个查询或其他操作,以获取所需信息。

使用elemMatch:

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

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

我所能想到的是你说的不对。除了您的
.populate()
参数看起来不正确之外,您在这里并没有显示太多上下文

以下是一个正确的列表,作为一个可复制的示例:

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();
  }
);
这将始终如一地产生如下结果:

Users.find({user_id: req.user.id}).populate('books',null,{bookname:"harry potter"}).exec(..);
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 } ] } ]

因此,请仔细查看您的数据和通话。
.populate()
调用需要匹配“路径”,然后还需要提供一个“匹配”来查询要填充的文档。

我在这里能想到的是,您的调用是错误的。除了您的
.populate()
参数看起来不正确之外,您在这里并没有显示太多上下文

以下是一个正确的列表,作为一个可复制的示例:

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();
  }
);
这将始终如一地产生如下结果:

Users.find({user_id: req.user.id}).populate('books',null,{bookname:"harry potter"}).exec(..);
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 } ] } ]

因此,请仔细查看您的数据和通话。
.populate()。这就是这里使用
.populate()
的含义。不是嵌入的文档数组,而是这些文档的
ObjectId
值。如果“books”是引用的“books”集合的
ObjectId
数组,则这没有任何用处。这就是这里使用
.populate()
的含义。不是嵌入的文档数组,而是这些文档的
ObjectId
值。