gpt4 book ai didi

node.js - Mongoose MongoDB 地理空间查询

转载 作者:太空宇宙 更新时间:2023-11-03 23:58:16 25 4
gpt4 key购买 nike

我有一个Item可以容纳数千至数十万份文档的集合。在该集合上,我想执行地理空间查询。使用 Mongoose,有两个选项 - find()和聚合管道。我已经展示了以下两者的实现:

Mongoose 模型

首先,以下是我的 Mongoose 模型的相关属性:

// Define the schema
const itemSchema = new mongoose.Schema({
// Firebase UID (in addition to the Mongo ObjectID)
owner: {
type: String,
required: true,
ref: 'User'
},
// ... Some more fields
numberOfViews: {
type: Number,
required: true,
default: 0
},
numberOfLikes: {
type: Number,
required: true,
default: 0
},
location: {
type: {
type: 'String',
default: 'Point',
required: true
},
coordinates: {
type: [Number],
required: true,
},
}
}, {
timestamps: true
});

// 2dsphere index
itemSchema.index({ "location": "2dsphere" });

// Create the model
const Item = mongoose.model('Item', itemSchema);

查找查询

// These variables are populated based on URL Query Parameters.
const match = {};
const sort = {};

// Query to make.
const query = {
location: {
$near: {
$maxDistance: parseInt(req.query.maxDistance),
$geometry: {
type: 'Point',
coordinates: [parseInt(req.query.lng), parseInt(req.query.lat)]
}
}
},
...match
};

// Pagination and Sorting
const options = {
limit: parseInt(req.query.limit),
skip: parseInt(req.query.skip),
sort
};

const items = await Item.find(query, undefined, options).lean().exec();

res.send(items);

聚合管道

假设需要计算距离:

// These variables are populated based on URL Query Parameters.
const query = {};
const sort = {};

const geoSpatialQuery = {
$geoNear: {
near: {
type: 'Point',
coordinates: [parseInt(req.query.lng), parseInt(req.query.lat)]
},
distanceField: "distance",
maxDistance: parseInt(req.query.maxDistance),
query,
spherical: true
}
};

const items = await Item.aggregate([
geoSpatialQuery,
{ $limit: parseInt(req.query.limit) },
{ $skip: parseInt(req.query.skip) },
{ $sort: { distance: -1, ...sort } }
]).exec();

res.send(items);

编辑 - 修改记录的示例

这是一个文档示例,其所有属性均来自 Item收藏:

{
"_id":"5cd08927c19d1dd118d39a2b",
"imagePaths":{
"standard":{
"images":[
"users/zbYmcwsGhcU3LwROLWa4eC0RRgG3/5cd08927c19d1dd118d39a2b/images/Image-aafe69c7-f93e-411e-b75d-319042068921-standard.jpg",
"users/zbYmcwsGhcU3LwROLWa4eC0RRgG3/5cd08927c19d1dd118d39a2b/images/Image-397c95c6-fb10-4005-b511-692f991341fb-standard.jpg",
"users/zbYmcwsGhcU3LwROLWa4eC0RRgG3/5cd08927c19d1dd118d39a2b/images/Image-e54db72e-7613-433d-8d9b-8d2347440204-standard.jpg",
"users/zbYmcwsGhcU3LwROLWa4eC0RRgG3/5cd08927c19d1dd118d39a2b/images/Image-c767f54f-7d1e-4737-b0e7-c02ee5d8f1cf-standard.jpg"
],
"profile":"users/zbYmcwsGhcU3LwROLWa4eC0RRgG3/5cd08927c19d1dd118d39a2b/images/Image-51318c32-38dc-44ac-aac3-c8cc46698cfa-standard-profile.jpg"
},
"thumbnail":"users/zbYmcwsGhcU3LwROLWa4eC0RRgG3/5cd08927c19d1dd118d39a2b/images/Image-51318c32-38dc-44ac-aac3-c8cc46698cfa-thumbnail.jpg",
"medium":"users/zbYmcwsGhcU3LwROLWa4eC0RRgG3/5cd08927c19d1dd118d39a2b/images/Image-51318c32-38dc-44ac-aac3-c8cc46698cfa-medium.jpg"
},
"location":{
"type":"Point",
"coordinates":[
-110.8571443,
35.4586858
]
},
"numberOfViews":0,
"numberOfLikes":0,
"monetarySellingAmount":9000,
"exchangeCategories":[
"Math"
],
"itemCategories":[
"Sports"
],
"title":"My title",
"itemDescription":"A description",
"exchangeRadius":10,
"owner":"zbYmcwsGhcU3LwROLWa4eC0RRgG3",
"reports":[],
"createdAt":"2019-05-06T19:21:13.217Z",
"updatedAt":"2019-05-06T19:21:13.217Z",
"__v":0
}

问题

基于以上,我想问几个问题。

  1. 我的普通 Mongoose 查询实现和使用聚合管道之间是否存在性能差异?

  2. 这样说是否正确 neargeoNearnearSphere 非常相似当使用2dsphere时使用 GeoJSON 进行索引 - 除了 geoNear提供额外的数据和默认限制?也就是说,虽然单位不同,但两个查询 - 概念上 - 都会显示某个位置特定半径内的相关数据,尽管该字段名为 radius对于 nearSpheremaxDistancenear/geoNear .

  3. 以我上面的示例为例,使用 skip 的性能损失会如何?得到缓解但仍然能够在查询和聚合中实现分页?

  4. find()函数允许使用可选参数来确定将返回哪些字段。聚合管道采用 $project阶段做同样的事情。有没有具体的顺序,其中 $project应该在管道中使用来优化速度/效率,还是不重要?

我希望 Stack Overflow 规则允许这种类型的问题。谢谢。

最佳答案

我尝试使用 2dsphere 索引进行以下查询。我使用了聚合管道
对于以下查询。

db.items.createIndex({location:"2dsphere"})

使用聚合管道时,它为您提供了结果集上的更大灵 active 。此外,聚合管道将提高运行地理相关搜索的性能。

db.items.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [ -110.8571443 , 35.4586858 ] },
key: "location",
distanceField: "dist.calculated",
minDistance: 2,
query: { "itemDescription": "A description" }
}])

关于您关于 $skip 的问题,下面的问题将使您对 $skip 操作有更多的了解 $skip and $limit in aggregation framework

您可以根据需要使用$project。在我们的例子中,我们使用超过 1000 万个数据的 $project 并没有遇到太大的性能问题

关于node.js - Mongoose MongoDB 地理空间查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55996638/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com