Node.js / Mongoose – 过滤嵌套的文档
长时间的听众第一次来电:-)
我search了相当长的时间,并没有完全find我的问题在这里的答案。 我正在寻找一种方法,或者想知道“正确”的方式,只返回一个嵌套mongoose模式内的特定项目。
所以,让我说我有这个例子。
var mongoose = require('mongoose') var Schema = mongoose.Schema var conn = mongoose.connect('mongodb://localhost/testjs'); Bar = new Schema({ text: String }); Foo = new Schema({ bar: [Bar] }); var Foo = mongoose.model('Foo', Foo); // Clean up the DB Foo.find({}, function(err, res) { for (i in res) { res[i].remove() } }); var foo = new Foo() foo.bar.push({"text":"Hi"}) foo.bar.push({"text":"Bye"}) foo.bar.push({"text":"Hey"}) foo.save( function(err){ var r = Foo .where('bar.text').equals('Hi') .select('bar.text') .exec(function(err, res) { console.log(res) }) } );
结果
[ { _id: 546c235cea0f16dc0d85a60f, bar: [ { text: 'Hi' }, { text: 'Bye' }, { text: 'Hey' } ] } ]
从查询中,我会希望它只能返回
[ { _id: 546c235cea0f16dc0d85a60f, bar: [ { text: 'Hi' } ] } ]
所以我想这引出了几个问题:
- 有没有更好的方式来构build这个查询?
- 这是典型的行为,它是要循环的结果,只是拔出我所需要的?
- 对于原始查询,为什么它会返回所有的字段,而不是我在'where'语句中指定的字段?
这是典型的行为
是的,这是mongodb
如何执行projection
操作。
.where("bar.text").equals("Hi")
,这部分查询称为find()
部分。 它匹配所有的logging,具有bar.text
的值为Hi
。
对于原始查询,为什么它会返回所有的字段,而不是我在'where'语句中指定的字段?
.select("bar.text")
,这是projection
部分。 只投射我们想要的那些字段。这对除数组内的字段以外的字段的预期工作,因为在特定的深度,将只存在一个唯一的 field
。 但是在数组的情况下,可以有相同深度的“n”个文档具有相同的字段。 投影数组元素时,将显示在该级别具有该特定字段的所有子文档。 这是非常有意义的。
而且这是循环的结果,只是拔出我所需要的?
没有。下面有更好的解释。
有没有更好的方式来构build这个查询?
如果您确定数组中只包含一个匹配查询条件的文档,则可以使用$
(位置投影)运算符。
foo.save( function(err){ var r = Foo.find({'bar.text':'Hi'},{'bar.$':1},function(err, res) { console.log(res) });});
如果您不确定数组中有多less个文档,并且字段值为Hi
,则可以使用聚合运算符pipe道,如下所示:
foo.save( function(err){ var r = Foo.aggregate([ {$match:{"bar.text":"Hi"}}, {$unwind:"$bar"}, {$match:{"bar.text":"Hi"}}, {$group:{"_id":"$_id","bars":{$push:"$bar"}}} ],function(err, res) { console.log(res) });});