【发布时间】:2016-08-06 01:48:32
【问题描述】:
我正在尝试使用 Meteor 的 find().fetch() 过滤返回的数据集以仅包含一个对象,如果我查询单个子文档但我收到多个子文档,它似乎不是很有用,有些甚至不包含任何匹配的条款。
我有一个简单的混合数据集合,如下所示:
{
"_id" : ObjectId("570d20de3ae6b49a54ee01e7"),
"name" : "Entertainment",
"items" : [
{
"_id" : ObjectId("57a38b5f2bd9ac8225caff06"),
"slug" : "this-is-a-long-slug",
"title" : "This is a title"
},
{
"_id" : ObjectId("57a38b835ac9e2efc0fa09c6"),
"slug" : "mc",
"title" : "Technology"
}
]
}
{
"_id" : ObjectId("570d20de3ae6b49a54ee01e8"),
"name" : "Sitewide",
"items" : [
{
"_id" : ObjectId("57a38bc75ac9e2efc0fa09c9"),
"slug" : "example",
"name" : "Single Example"
}
]
}
我可以使用 MongoDB shell 轻松查询嵌套 items 数组中的特定对象,如下所示:
db.categories.find( { "items.slug": "mc" }, { "items.$": 1 } );
这会返回良好的数据,它只包含我想要使用的单个对象:
{
"_id" : ObjectId("570d20de3ae6b49a54ee01e7"),
"items" : [
{
"_id" : ObjectId("57a38b985ac9e2efc0fa09c8")
"slug" : "mc",
"name" : "Single Example"
}
]
}
但是,如果直接尝试在 Meteor 中进行类似查询:
/* server/publications.js */
Meteor.publish('categories.all', function () {
return Categories.find({}, { sort: { position: 1 } });
});
/* imports/ui/page.js */
Template.page.onCreated(function () {
this.subscribe('categories.all');
});
Template.page.helpers({
items: function () {
var item = Categories.find(
{ "items.slug": "mc" },
{ "items.$": 1 } )
.fetch();
console.log('item: %o', item);
}
});
结果并不理想,因为它返回了整个匹配的块,以及嵌套的items 数组中的每个对象:
{
"_id" : ObjectId("570d20de3ae6b49a54ee01e7"),
"name" : "Entertainment",
"boards" : [
{
"_id" : ObjectId("57a38b5f2bd9ac8225caff06")
"slug" : "this-is-a-long-slug",
"name" : "This is a title"
},
{
"_id" : ObjectId("57a38b835ac9e2efc0fa09c6")
"slug" : "mc",
"name" : "Technology"
}
]
}
我当然可以使用 for 循环进一步过滤返回的游标以获取所需的对象,但这在处理更大的数据集时似乎不可扩展且效率极低。
我不明白为什么 Meteor 的 find 返回的数据集与 MongoDB 的 shell find 完全不同,唯一合理的解释是两个函数签名不同。
我是否应该将嵌套集合分解为更小的集合并采用更相关的数据库方法(即存储对 ObjectID 的引用)并从集合到集合查询数据,或者是否有更强大的方法可以有效地过滤大数据设置为仅包含匹配对象的单个对象,如上所示?
【问题讨论】:
-
Meteor 的客户端实现称为 MiniMongo。它只实现了 MongoDB 选择器的一个子集。
标签: javascript mongodb meteor