Как создать индекс во вложенной коллекции MongoDB?

#python #mongodb #pymongo #geojson

#питон #mongodb #пимонго #геойсон

Вопрос:

У меня есть коллекция 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 в местоположение офиса каждого участника? До сих пор с ПиМонго я использовал:

 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, это результат приведенного выше запроса, когда в оболочке используется .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"  

Комментарии:

1. Спасибо, что указали на это! Это моя ошибка, это была ошибка транскрипции, когда я печатал этот пост. На самом деле это Location тоже есть в базе данных, я исправил исходный вопрос, чтобы отразить это. Проблема с кодом все еще существует. Хотя спасибо, что указали на это!

2. Можете ли вы опубликовать результаты от участников.объясните(правда). aggregate (), чтобы мы могли увидеть, как монго интерпретирует ваш запрос?

3. Конечно, я обновил исходное сообщение с выводом.

4. Похоже, что вы изменили длину/латераль в запросе. Точки [-5, 54] и [54,-5] являются действительными точками, но они находятся на расстоянии 8500км друг от друга.