#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км друг от друга.