uni-app 聚合阶段的geoNear无法获取到符合条件的全部数据
uni-app 聚合阶段的geoNear无法获取到符合条件的全部数据
产品分类:
uniCloud/腾讯云
App下载地址或H5网址:
www.xnkj.ren
示例代码:
console.log(`--- 附近 ---`);
let {locData} = self,
{longitude, latitude} = locData,
query = {
deleted: _.neq(true), // 未删除
offShelves: _.neq(true), // 未下架
"community.0.public": _.neq(false) // 公开
};
if(unrefresh){
let gots = [];
list.forEach( x => gots.push(x._id));
console.log({gots});
query._id = _.nin(gots);
};
let geoNear = {
distanceField: 'distance',
maxDistance: 100000,
minDistance: 0,
spherical: true,
near: new db.Geo.Point(longitude, latitude),
key: "geoPoint"
},
dyn = {
...query,
type: "dynamic"
},
que = {
...query,
type: "question",
},
reso = {
...query,
type: "resource",
},
tas = {
...query,
type: "task",
taskData: {
progress: _.or([_.exists(false), _.size(0)]), // 未被接
"order.0.paid": true, // 已支付押金
repealed: _.neq(true) // 未撤销
}
},
query1;
if(keyword == "推荐"){
query1 = _.or([dyn, que, reso, tas]);
}else if(keyword == "动态"){
query1 = dyn;
}else if(keyword == "问题"){
query1 = que;
}else if(keyword == "资源"){
query1 = reso;
}else if(keyword == "任务"){
query1 = tas;
};
db.collection('xn-user-action').aggregate().geoNear(geoNear).lookup({
from: 'uni-id-users',
let: {
creator: '$creatorID',
},
pipeline: $.pipeline().match(_.expr($.eq(['$_id','$$creator']))).project({avatar_file:1, nickname:1}).done(),
as: 'creatorID'
}).lookup({
from: 'xn-community',
let: {
id: '$communityID',
},
pipeline: $.pipeline().match(_.expr($.eq(['$_id','$$id']))).project({public:1, name:1}).done(),
as: 'community'
}).lookup({
from: "xn-order",
let: {
orderID: "$taskData.orderID"
},
pipeline: $.pipeline().match(_.expr($.eq(['$orderID', '$$orderID']))).project({paid: 1}).done(),
as: 'taskData.order'
})
.match(query1)
.sort({creatTime: -1})
.limit(20)
.end().then(({result:{data:newList}})=>{
console.log(`一共${newList.length}条数据`);
resolve(newList);
newList.forEach(x=> handleData(x));
if(unrefresh){
action.list = list.concat(newList);
}else action.list = newList;
if(newList.length < 20){
self.$nextTick().then(()=>{
action.status = 'nomore';
});
}else{
self.$nextTick().then(()=>{
action.status = 'loadmore';
});
};
}).catch(err=>{
console.log(err)
reject(err);
})
7 回复
我看你的sort使用的是createTime,在数据库的20条数据能按照这个做出唯一排序吗?
我把sort去掉也是一样的,甚至切换一下定位后,一条数据都获取不到了
回复 1***@qq.com: 整理个简单的示例发一下吧
回复 DCloud_uniCloud_WYQ: 就是复杂聚合查询,无法按照预期获取到数据
回复 1***@qq.com: 地理位置查询
回复 1***@qq.com: 导出一份db_init.json,以及对应的有问题的聚合查询,其中不要出现变量
在使用 uni-app 进行 MongoDB 聚合查询时,如果你发现 geoNear
阶段无法获取到符合条件的全部数据,可能有以下几个原因和解决方法:
1. 检查集合是否有2d或2dsphere索引
geoNear
阶段要求集合必须有一个2d
或2dsphere
索引。如果没有创建相应的索引,geoNear
将无法正常工作。- 确保你在目标集合上创建了正确的索引。例如:
db.collection.createIndex({ location: "2dsphere" });
2. 检查坐标数据的格式
geoNear
要求地理位置数据的格式必须符合 MongoDB 的地理空间数据类型。通常,坐标数据应该是一个包含type
和coordinates
的 GeoJSON 对象。- 例如:
{ "location": { "type": "Point", "coordinates": [longitude, latitude] } }
3. 检查查询范围
geoNear
默认会返回距离查询点最近的 100 个文档。如果你需要获取更多的数据,可以通过limit
参数来调整返回的文档数量。- 例如:
db.collection.aggregate([ { $geoNear: { near: { type: "Point", coordinates: [longitude, latitude] }, distanceField: "distance", maxDistance: 10000, // 最大距离(单位:米) spherical: true, limit: 1000 // 返回最多 1000 个文档 } } ]);
4. 检查 maxDistance
参数
maxDistance
参数用于限制查询的最大距离。如果maxDistance
设置得太小,可能会导致返回的文档数量不足。- 确保
maxDistance
设置合理,或者不设置该参数以获取所有符合条件的文档。
5. 检查 spherical
参数
- 如果你使用的是
2dsphere
索引,确保将spherical
参数设置为true
,以启用球面几何计算。 - 例如:
db.collection.aggregate([ { $geoNear: { near: { type: "Point", coordinates: [longitude, latitude] }, distanceField: "distance", spherical: true } } ]);
6. 检查数据是否在查询范围内
- 确保你的数据确实在查询范围内。如果数据不在查询范围内,
geoNear
将无法返回任何结果。
7. 检查聚合管道的其他阶段
- 如果
geoNear
阶段后面还有其他聚合阶段(如$match
、$project
等),确保这些阶段没有过滤掉你需要的文档。
8. 调试和日志
- 使用
console.log
或调试工具检查聚合管道的每个阶段的输出,确保数据在管道中正确传递。
示例代码
以下是一个完整的 geoNear
聚合查询示例:
db.collection.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [longitude, latitude] },
distanceField: "distance",
maxDistance: 10000, // 最大距离(单位:米)
spherical: true,
limit: 1000 // 返回最多 1000 个文档
}
}
]);