Javascript Nodejs+;mongodb:如何查询$ref字段?
我正在使用MongoDB和nodejs REST服务,该服务公开了存储在其中的数据。我有一个关于如何查询我使用$ref的数据的问题 以下是一个对象的示例,其中包含对另一个集合中另一个对象(细节)的引用:Javascript Nodejs+;mongodb:如何查询$ref字段?,javascript,node.js,mongodb,dbref,Javascript,Node.js,Mongodb,Dbref,我正在使用MongoDB和nodejs REST服务,该服务公开了存储在其中的数据。我有一个关于如何查询我使用$ref的数据的问题 以下是一个对象的示例,其中包含对另一个集合中另一个对象(细节)的引用: { "_id" : ObjectId("5962c7b53b6a02100a000085"), "Title" : "test", "detail" : { "$ref" : "ObjDetail", "$id" : ObjectId("5
{
"_id" : ObjectId("5962c7b53b6a02100a000085"),
"Title" : "test",
"detail" : {
"$ref" : "ObjDetail",
"$id" : ObjectId("5270c7b11f6a02100a000001")
},
"foo" : bar
}
实际上,使用Node.js和mongodb模块,我做了以下工作:
db.collection("Obj").findOne({"_id" : new ObjectID("5962c7b53b6a02100a000085"},
function(err, item) {
db.collection(item.$ref).findOne({"_id" : item.$id}, function(err,subItem){
...
});
});
事实上,我进行了两次查询,得到了两个对象。这是一种“延迟加载”(不完全是,但几乎是)
我的问题很简单:是否可以在一个查询中检索整个对象图
谢谢不,不行
要解析DBREF,应用程序必须执行其他查询以返回引用的文档。许多驱动程序都有自动形成DBRef查询的助手方法。驱动程序不会自动将DBREF解析为文档
从MongoDB文档中。是否可以使用单个MongoDB查询获取父对象及其$ref 不,这是不可能的。 Mongo没有对REF的内部支持,因此填充它们取决于应用程序(请参阅) 但是,是否可以使用单个node.js命令获取父对象及其所有ref
是的,这是可能的。你可以用。它有ref的人口支持。您需要稍微更改数据模型以使其正常工作,但这正是您所需要的。当然,要做到这一点,Mongoose将执行与您相同的两个MongoDB查询。不,MongoDB的驱动程序很少包含对
DBRef
的特殊支持。原因有两个:
DBRef
类型,而是直接存储ObjectId
。正如您所看到的,DBRef
除了为每个引用需要大量重复的磁盘空间外,实际上没有任何好处,因为更丰富的对象必须与其类型信息一起存储。无论哪种方式,您都应该考虑存储包含引用集合文档的字符串的潜在不必要开销。p>
许多开发人员和MongoDb,Inc.在现有基本驱动程序的基础上添加了对象文档映射层。MongoDb和Nodejs的一个流行选项是Mongoose。由于MongoDb服务器对引用的文档没有真正的感知,因此引用的责任转移到了客户端。由于一致引用给定文档中的特定集合更为常见,因此Mongoose可以将引用定义为模式。Mongoose不是无模式的
如果您接受拥有并使用模式是有用的,那么Mongoose绝对值得一看。它可以从一组文档中高效地获取一批相关文档(来自单个集合)。它总是使用本机驱动程序,但它通常非常高效地执行操作,并从更复杂的应用程序体系结构中消除一些繁琐的工作
我强烈建议您看看populate
方法(),看看它能做什么
Demo /* Demo would be a Mongoose Model that you've defined */
.findById(theObjectId)
.populate('detail')
.exec(function (err, doc) {
if (err) return handleError(err);
// do something with the single doc that was returned
})
如果使用populate
,而不是始终返回单个文档的findById
,则所有返回文档的详细信息
属性将自动填充。它还可以多次请求相同的引用文档
如果您不使用MangeOSE,我建议您考虑一个缓存层以避免在可能的时候做客户端引用连接,并使用<代码> $$在/<代码>查询运算符中尽可能批量。p> 我通过下一个示例达到了所需的结果:
collection.find({}, function (err, cursor) {
cursor.toArray(function (err, docs) {
var count = docs.length - 1;
for (i in docs) {
(function (docs, i) {
db.dereference(docs[i].ref, function(err, doc) {
docs[i].ref = doc;
if (i == count) {
(function (docs) {
console.log(docs);
})(docs);
}
});
})(docs, i)
}
});
});
不确定it解决方案是最好的,但这是我发现的最简单的解决方案。Vladimir的答案仍然无效,因为db.dereference方法已从MongoDB Nodejs API中删除: db实例对象已简化。我们已删除以下方法: 由于服务器中不推荐使用db引用,导致db.dereference
据我所知,节点mongodb本机驱动程序无法为您解析这些引用。谢谢,我来看看mongoose。