我正在尝试使用通配符
$near
和$geometry
从数据库文档内的现有数组中检索一个特定对象。
我有一个看起来像这样的模型:
const schema = new mongoose.Schema({
name: {...},
email: {...},
...
locations: [
{
name: String,
address: String,
mapurl: String,
location: {
type: {
type: String,
default: "Point",
},
coordinates: [
{
type: Number,
},
],
},
},
],
}
像这样索引架构:
schema.index({ "locations.location": "2dsphere" });
数据库中的文档如下所示:
{
"_id": ...,
"name": ...,
"email": ...,
"locations": [
{
"name": "name 1",
"address": "address 1",
"mapurl": "https://maps.google.com/SOME_MAP_URL_1",
"location": {
"type": "Point",
"coordinates": [
11.1111,
12.2222
]
},
"_id": {
"$oid": "..."
}
},
{
"name": "name 2",
"address": "address 2",
"mapurl": "https://maps.google.com/SOME_MAP_URL_2",
"location": {
"type": "Point",
"coordinates": [
22.3333,
23.4444
]
},
"_id": {
"$oid": "..."
}
},
{
"name": "name 3",
"address": "address 3",
"mapurl": "https://maps.google.com/SOME_MAP_URL_3",
"location": {
"type": "Point",
"coordinates": [
33.4444,
34.5555
]
},
"_id": {
"$oid": "..."
}
},
],
}
我正在尝试在数据库中查询数组中的特定对象,然后使用
.select()
: 从该对象获取我需要的所有信息
const q = {
_id: place._id,
"locations.location": {
$near: {
$geometry: {
type: "Point",
coordinates: [22.333, 23.444]
},
$maxDistance: 100, // 100m
},
},
};
const storeCoords = await Place.find(q).select("locations.location");
结果,我期望从数组中仅获取一个距离提供的坐标近 100 米的特定对象,但相反,我得到的是整个数组,其中包含所有现有对象,包括我需要的对象。
预期结果:
{
"coords": [
{
"_id": "...",
"locations": [
{
"location": {
"type": "Point",
"coordinates": [22.3333, 23.4444]
}
},
]
}
]
}
实际结果:
{
"coords": [
{
"_id": "...",
"locations": [
{
"location": {
"type": "Point",
"coordinates": [11.1111, 12.2222]
}
},
{
"location": {
"type": "Point",
"coordinates": [22.3333, 23.4444]
}
},
{
"location": {
"type": "Point",
"coordinates": [33.4444, 34.5555]
}
}
]
}
]
}
我可能会以错误的方式或完全错误的通配符使用
$near
和 $geometry
。
请指教。
如果您只想获取一份文档,那么您应该使用 findOne。 但就您而言,它不会给您期望的答案,因为 findOne 会返回与数据库中的条件匹配的第一个文档,而该文档可能不是最近的文档。
在这种情况下,您应该使用“$geoNear”运算符。
https://www.mongodb.com/docs/manual/reference/operator/aggregation/geoNear/
这是可能有帮助的聚合
const aggregationQuery = [
{
$match: {
_id: place._id
}
},
{
$unwind: "$locations"
},
{
$geoNear: {
near: {
type: "Point",
coordinates: [22.333, 23.444]
},
distanceField: "distance",
spherical: true,
maxDistance: 100 // 100m
}
},
{
$limit: 1 // Limit to only the nearest location
},
{
$project: {
_id: 1,
location: "$locations.location"
}
}
];
const storeCoords = await Place.aggregate(aggregationQuery);