如何在嵌套的 MongoDB 集合中创建索引?
Posted
技术标签:
【中文标题】如何在嵌套的 MongoDB 集合中创建索引?【英文标题】:How to create an index in a nested MongoDB collection? 【发布时间】:2022-01-07 12:18:12 【问题描述】:我有一个 MongoDB 集合,其中包括人员和两组带有 GeoJSON 坐标的联系方式 - 办公室和家庭。在这个集合中,我想在这些坐标字段上添加一个 2dsphere 索引,这样我就可以创建一个函数来查找离用户最近的办公室。
我的收藏(缩小一点以删除一些敏感数据)如下所示:
"_id" : ObjectId("61a64ce6c7c66e3e3ca71ea3"),
"MemberName" : "Somename",
"MemberLastName" : "name",
"MemberFirstName" : "Some",
"Province" : "SomeProvince",
"MemberPrefix" : "Ms",
"ContactDetails" : [
"_id" : ObjectId("61a64ce7c7c66e3e3ca7235d"),
"MemberName" : "SomeName",
"AddressType" : "Office",
"Address1" : "TestTown",
"Townland" : "TestTown",
"TownCity" : "Testtesttestlol",
"Postcode" : "TTT 4TT",
"Location" :
"type" : "Point",
"coordinates" : [
-5.872474572689,
54.578308571336
]
,
"_id" : ObjectId("61a64ce7c7c66e3e3ca7235e"),
"MemberName" : "SomeName",
"AddressType" : "Home",
"Address1" : "HomeAddress",
"Townland" : "TestTown",
"TownCity" : "TownTest",
"Postcode" : "TT5 H55",
"Location" :
"type" : "Point",
"coordinates" : [
-5.828601611087,
54.59907579121
]
],
我的问题是如何将 2dsphere 索引添加到每个成员的办公位置?到目前为止,我使用过 PyMongo:
members.create_index([("ContactDetails.Location", pymongo.GEOSPHERE)])
报告该字段的索引已成功创建。但是,当我尝试实际使用它来检索数据时,控制台没有输出任何内容。我的钥匙没问题还是我制作的测试脚本有问题?
geotest.py:
from pymongo import MongoClient
client = MongoClient("mongodb://127.0.0.1:27017")
db = client.memberDB
members = db.members
for neighbour in members.aggregate( [
"$geoNear" :
"near" :
"type" : "Point",
"coordinates" :
[54.89398396718853, -6.045212206625715] ,
"maxDistance": 50000,
"minDistance" : 1,
"distanceField" : "distance",
"spherical" : True
]):
print(neighbour)
编辑: 根据 R2D2 的要求,这是在 shell 中使用 .explain() 时上述查询的输出:
"explainVersion" : "1",
"stages" : [
"$geoNearCursor" :
"queryPlanner" :
"namespace" : "memberDB.members",
"indexFilterSet" : false,
"parsedQuery" :
"ContactDetails.Location" :
"$nearSphere" :
"type" : "Point",
"coordinates" : [
54.88053164695987,
-6.458416339402716
]
,
"$minDistance" : 1,
"$maxDistance" : 5000000
,
"queryHash" : "003B7873",
"planCacheKey" : "13FEDF92",
"maxIndexedOrSolutionsReached" : false,
"maxIndexedAndSolutionsReached" : false,
"maxScansToExplodeReached" : false,
"winningPlan" :
"stage" : "GEO_NEAR_2DSPHERE",
"keyPattern" :
"ContactDetails.Location" : "2dsphere"
,
"indexName" : "ContactDetails.Location_2dsphere",
"indexVersion" : 2,
"inputStage" :
"stage" : "FETCH",
"inputStage" :
"stage" : "IXSCAN",
"keyPattern" :
"ContactDetails.Location" : "2dsphere"
,
"indexName" : "ContactDetails.Location_2dsphere",
"isMultiKey" : true,
"multiKeyPaths" :
"ContactDetails.Location" : [
"ContactDetails"
]
,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" :
"ContactDetails.Location" : [
"[-5620492334958379007, -5476377146882523137]",
"[-5476377146882523135, -5332261958806667265]",
"[1152921504606846977, 1297036692682702847]",
"[1369094286720630784, 1369094286720630784]",
"[1423137482249076736, 1423137482249076736]",
"[1432144681503817729, 1441151880758558719]",
"[1441151880758558721, 1585267068834414591]",
"[1585267068834414593, 1729382256910270463]",
"[1729382256910270465, 2305843009213693951]",
"[2305843009213693953, 2882303761517117439]",
"[2882303761517117441, 3026418949592973311]",
"[3386706919782612992, 3386706919782612992]",
"[3386706919782612993, 3422735716801576959]",
"[3422735716801576961, 3458764513820540927]",
"[3458764513820540929, 3602879701896396799]",
"[4035225266123964417, 4611686018427387903]",
"[4611686018427387905, 4647714815446351871]",
"[4683743612465315840, 4683743612465315840]"
]
,
"rejectedPlans" : [ ]
,
"executionStats" :
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 1,
"totalKeysExamined" : 1,
"totalDocsExamined" : 0,
"executionStages" :
"stage" : "GEO_NEAR_2DSPHERE",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 27,
"advanced" : 0,
"needTime" : 26,
"needYield" : 0,
"saveState" : 1,
"restoreState" : 1,
"isEOF" : 1,
"keyPattern" :
"ContactDetails.Location" : "2dsphere"
,
"indexName" : "ContactDetails.Location_2dsphere",
"indexVersion" : 2,
"searchIntervals" : [
"minDistance" : 1,
"maxDistance" : 5000000,
"maxInclusive" : true,
"nBuffered" : 0,
"nReturned" : 0
],
"inputStage" :
"stage" : "FETCH",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"docsExamined" : 0,
"alreadyHasObj" : 0,
"inputStage" :
"stage" : "IXSCAN",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"keyPattern" :
"ContactDetails.Location" : "2dsphere"
,
"indexName" : "ContactDetails.Location_2dsphere",
"isMultiKey" : true,
"multiKeyPaths" :
"ContactDetails.Location" : [
"ContactDetails"
]
,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" :
"ContactDetails.Location" : [
"[-5620492334958379007, -5476377146882523137]",
"[-5476377146882523135, -5332261958806667265]",
"[1152921504606846977, 1297036692682702847]",
"[1369094286720630784, 1369094286720630784]",
"[1423137482249076736, 1423137482249076736]",
"[1432144681503817729, 1441151880758558719]",
"[1441151880758558721, 1585267068834414591]",
"[1585267068834414593, 1729382256910270463]",
"[1729382256910270465, 2305843009213693951]",
"[2305843009213693953, 2882303761517117439]",
"[2882303761517117441, 3026418949592973311]",
"[3386706919782612992, 3386706919782612992]",
"[3386706919782612993, 3422735716801576959]",
"[3422735716801576961, 3458764513820540927]",
"[3458764513820540929, 3602879701896396799]",
"[4035225266123964417, 4611686018427387903]",
"[4611686018427387905, 4647714815446351871]",
"[4683743612465315840, 4683743612465315840]"
]
,
"keysExamined" : 1,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0
,
"allPlansExecution" : [ ]
,
"nReturned" : NumberLong(0),
"executionTimeMillisEstimate" : NumberLong(0)
],
"serverInfo" :
"host" : "Orthanc",
"port" : 27017,
"version" : "5.0.3",
"gitVersion" : "657fea5a61a74d7a79df7aff8e4bcf0bc742b748"
,
"serverParameters" :
"internalQueryFacetBufferSizeBytes" : 104857600,
"internalQueryFacetMaxOutputDocSizeBytes" : 104857600,
"internalLookupStageIntermediateDocumentMaxSizeBytes" : 104857600,
"internalDocumentSourceGroupMaxMemoryBytes" : 104857600,
"internalQueryMaxBlockingSortMemoryUsageBytes" : 104857600,
"internalQueryProhibitBlockingMergeOnMongoS" : 0,
"internalQueryMaxAddToSetBytes" : 104857600,
"internalDocumentSourceSetWindowFieldsMaxMemoryBytes" : 104857600
,
"command" :
"aggregate" : "members",
"pipeline" : [
"$geoNear" :
"near" :
"type" : "Point",
"coordinates" : [
54.88053164695987,
-6.458416339402716
]
,
"maxDistance" : 5000000,
"minDistance" : 1,
"distanceField" : "distance",
"spherical" : "true"
],
"cursor" :
,
"$db" : "memberDB"
,
"ok" : 1
【问题讨论】:
【参考方案1】:您的代码似乎有错字,您需要在以下位置创建索引:
"ContactDetails.location"
代替:
"ContactDetails.Location"
【讨论】:
感谢您指出这一点!那是我的错,这是我输入这篇文章时的转录错误。它实际上也是数据库中的Location
,我已经修复了原始问题以反映这一点。代码的问题仍然存在。感谢您指出这一点!
您能否发布 members.explain(true).aggregate() 的输出,以便我们了解 mongo 如何解释您的查询?
当然,我已经用输出更新了原始帖子。
您的查询中似乎有 long/lat 反转。点 [-5, 54] 和 [54,-5] 都是有效点,但它们相距 8500 公里。以上是关于如何在嵌套的 MongoDB 集合中创建索引?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Robo 3T(原 Robomongo)中创建 Mongodb 索引?
如何使用 golang 和 mgo 库在 mongodb 中创建文本索引?
如何在不在 MongoDB 中创建集合的情况下创建 Mongoose 模型?