如何在$geoNear之后填充子文档
How do I populate sub-document after $geoNear
我正在使用NodeJs和Mongoose,并构建一个功能来列出附近的交易。
Deal.db.db.command({
"geoNear": Deal.collection.name,
"near": [23,67],
"spherical": true,
"distanceField": "dis"
}, function (err, documents) {
if (err) {
return next(err);
}
console.log(documents);
});
交易模式:
var dealSchema = new mongoose.Schema({
title: String,
merchant: {
type: mongoose.Schema.Types.ObjectId,
ref: Merchant,
index: true
}
});
在这里,我可以获得所有交易以及它们与当前位置的距离。在Deal模式中,我有一个商人作为参考对象。
如何用每个返回的Deal对象填充商家?我是否需要遍历所有返回的Deal对象并手动填充?
事实证明这有点有趣。当然,您不想真正"深入"本机驱动程序部分,尽管您可能会在解决方案2中这样做。这导致有几种方法可以做到这一点,而无需实际滚动自己的查询来手动匹配。
首先是一个小的设置。我只是从以前的测试中挑选了一些东西,而不是复制你的数据集。原理是一样的,所以一个基本的设置:
var mongoose = require('mongoose'),
async = require('async'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost');
var infoSchema = new Schema({
"description": String
});
var shapeSchema = new Schema({
"_id": String,
"amenity": String,
"shape": {
"type": { "type": String },
"coordinates": []
},
"info": { "type": Schema.Types.ObjectId, "ref": "Info" }
});
var Shape = mongoose.model( "Shape", shapeSchema );
var Info = mongoose.model( "Info", infoSchema );
本质上,一个模型包含"地理"信息,另一个模型仅引用了我们想要填充的一些信息。还有我对数据的懒惰修改:
{
"_id" : "P1",
"amenity" : "restaurant",
"shape" : { "type" : "Point", "coordinates" : [ 2, 2 ] }
}
{
"_id" : "P3",
"amenity" : "police",
"shape" : { "type" : "Point", "coordinates" : [ 4, 2 ] }
}
{
"_id" : "P4",
"amenity" : "police",
"shape" : { "type" : "Point", "coordinates" : [ 4, 4 ] }
}
{
"_id" : "P2",
"amenity" : "restaurant",
"shape" : { "type" : "Point", "coordinates" : [ 2, 4 ] },
"info" : ObjectId("539b90543249ff8d18e863fb")
}
因此,有一件事是我们可以期待的。事实证明,$near
查询非常简单,正如预期的排序一样:
var query = Shape.find(
{
"shape": {
"$near": {
"$geometry": {
"type": "Point",
"coordinates": [ 2, 4 ]
}
}
}
}
);
query.populate("info").exec(function(err,shapes) {
if (err) throw err;
console.log( shapes );
});
这只是调用了$near
运算符的标准.find()
。这是MongoDB 2.6的语法,所以就是这样。但结果排序正确,并按预期填充:
[
{ _id: 'P2',
amenity: 'restaurant',
info:
{ _id: 539b90543249ff8d18e863fb,
description: 'Jamies Restaurant',
__v: 0 },
shape: { type: 'Point', coordinates: [ 2, 4 ] } },
{ _id: 'P4',
amenity: 'police',
info: null,
shape: { type: 'Point', coordinates: [ 4, 4 ] } },
{ _id: 'P1',
amenity: 'restaurant',
info: null,
shape: { type: 'Point', coordinates: [ 2, 2 ] } },
{ _id: 'P3',
amenity: 'police',
info: null,
shape: { type: 'Point', coordinates: [ 4, 2 ] } }
]
这非常好,也是一种简单的调用方式。捕获?遗憾的是,将运算符更改为$geoNear
以考虑球形几何体会引发错误。所以,如果你想这样,你就不能只做你习惯的事情。
不过,另一种方法是mongoose有一个受支持的.geoNear()
函数。但就像db.command
调用一样,它不会返回接受.populate()
的mongoose文档或其他Model类型对象。解决方案只是玩一点输出:
var query = Shape.geoNear({
"type": "Point",
"coordinates": [ 2, 4 ]
},{spherical: true},function(err,shapes) {
if (err) throw err;
shapes = shapes.map(function(x) {
delete x.dis;
var a = new Shape( x.obj );
return a;
});
Shape.populate( shapes, { path: "info" }, function(err,docs) {
if (err) throw err;
console.log( docs );
});
所以这里返回的结果是一个原始对象数组。但是,只要进行一点操作,就可以将这些转换为.populate()
方法,该方法也可以从模型类中调用,如图所示。
结果当然是一样的,尽管字段顺序可能有点不同。而且您不需要自己迭代调用查询。这确实是.populate()
实际所做的全部,但我认为我们可以同意,使用.populate()
方法至少看起来干净得多,并且不会为此目的重新发明轮子。
- 正在对已提取的文档进行填充.有可能吗?如果有,怎么做
- 有没有一种方法可以找到一个匹配两个不同填充的文档,并在findOne()中获取他的文档
- 猫鼬在级联中填充嵌入式文档
- 如何填充子“引用”文档猫鼬数组
- 如何填充浏览器's用矩形显示的整个窗口/文档
- 我可以在mongoDB中找到基于填充条件的文档吗
- Mongoose如何填充引用的文档
- 是否有任何关于如何填充修订说明以及在什么条件下填充的文档
- 使用 JavaScript 模式填充文档
- 为什么不是文档.导致剪贴板填充的execCommand
- 在带有填充嵌套数组的mongoDB文档中查找并构建新的结果对象
- 如何附加点击事件在运行时,当我有一个数组中的所有id得到填充时,文档准备好了
- 填充有限数量的文档
- 猫鼬填充文档
- 如何在$geoNear之后填充子文档
- 我如何从模板节点复制并填充json数据,并用javascript将它们附加到文档中
- 向mongodb添加一个文档,并预先填充字符串的开始和结束
- 自动填充浏览器文档高度以滚动到任何元素
- Chrome中奇怪的文档正文右侧填充问题
- 在猫鼬中填充嵌入的文档