长时间听众第一次来电: - )
我已经搜索了相当多的时间,并且在这里找不到我的问题的答案。我正在寻找一种方式,或者想知道"正确的"方式,仅返回嵌套的mongoose Schema中的特定项。
让我说我有这个例子。
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' } ] } ]
所以我想这引出了几个问题:
答案 0 :(得分:1)
这是典型行为吗
是的,这是mongodb
执行projection
操作的方式。
.where("bar.text").equals("Hi")
,此部分查询称为find()
部分。它匹配所有记录,其值bar.text
为Hi
。
对于原始查询,为什么它会返回所有字段而不是我在'where'语句中指定的字段?
.select("bar.text")
,这是projection
部分。仅投影我们想要的那些字段。这对于除阵列内部以外的字段的预期工作,因为在特定深度,只有一个唯一 field
。但是在数组的情况下,可能存在具有相同深度的相同字段的'n'个文档。投影数组元素时,将显示在该级别具有此特定字段的所有子文档。这很有道理。
并且可以循环结果并提取我需要的内容吗?
没有。有更好的方法解释如下。
是否有更好的方法来构建此查询?
如果您确定该数组只包含一个与查询条件匹配的文档,则可以使用$
(位置投影)运算符。
foo.save(
function(err){
var r = Foo.find({'bar.text':'Hi'},{'bar.$':1},function(err, res) {
console.log(res)
});});
如果您不确定数组中包含字段值Hi
的文档数量,您可以使用聚合运算符管道,如下所示:
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)
});});