Questa è una di quelle domande a cui rispondere sia sì che no, poiché sì un array è supportato per la corrispondenza dei risultati ma probabilmente non è nemmeno quello che vuoi veramente considerando le restrizioni su come viene eseguita la corrispondenza.
Il cambiamento notevole di cui hai bisogno qui è che gli oggetti stessi non sono definiti in modo tale che MongoDB li riconoscerà come li hai attualmente formati. Esistono due moduli di ricerca di indici e generali con coppie di coordinate legacy (che è solo un punto x,y) o come GeoJSON con oggetti GeoJSON supportati. Il tuo problema è che hai un formato GeoJSON "psuedo" che non è realmente conforme alle specifiche e che stai cercando di accedere direttamente alle "coordinate", dove hai bisogno di un oggetto di livello superiore in questo modo:
{
"regions": [
{
"name": "penta",
"geometry": {
"type": "Polygon",
"coordinates": [[
[
-77.0322804898023610,
-12.1271067552781560
],
[
-77.0336792618036270,
-12.1255133434450870
],
[
-77.0326449349522590,
-12.1239143495252150
],
[
-77.0300991833209990,
-12.1238251884504540
],
[
-77.0299865305423740,
-12.1262000752832540
],
[
-77.0322804898023610,
-12.1271067552781560
]
]]
}
},
{
"name": "triangle",
"geometry": {
"type": "Polygon",
"coordinates": [[
[
-77.0313568040728570,
-12.1266573492018090
],
[
-77.0325788855552670,
-12.1246968022373030
],
[
-77.0300653204321860,
-12.1246233756874440
],
[
-77.0313568040728570,
-12.1266573492018090
]
]]
}
}
]
}
In modo che astragga la parte GeoJSON in modo che sia ben formata e separata dagli altri metadati che non fanno parte delle specifiche. Idealmente, indicizzeresti anche tu, sebbene non sia richiesto per $geoWithin
o $geoIntersects
aiuta sicuramente:
db.regions.createIndex({ "regions.geometry": "2dsphere" })
Definizione del percorso completo della definizione GeoJSON all'interno dell'elemento dell'array.
Quindi le query funzionano correttamente:
db.regions.find({
"regions.geometry" : {
"$geoIntersects" : {
"$geometry" : {
"type" : "Polygon" ,
"coordinates" : [[
[ -77.02877718955278 , -12.123750122669545],
[ -77.03457042574883 , -12.123750122669545],
[ -77.03457042574883 , -12.12736341792724],
[ -77.02877718955278 , -12.12736341792724],
[ -77.02877718955278 , -12.123750122669545]
]]
}
}
}
})
Che corrisponde al documento sopra. Ma ovviamente ci sono più oggetti nell'array, quindi la domanda è:quale di questi corrispondeva? A cui non esiste una risposta supportata, poiché MongoDB corrisponde al "documento" e non indica in alcun modo quale elemento dell'array è stato abbinato.
C'è un'opzione nell'aggregazione $geoNear
ciò consente la restituzione dell'oggetto abbinato, dove in questo caso sarebbe "il più vicino". E con dettagli del genere è quindi possibile utilizzare tali informazioni per abbinare quale elemento dell'array con metadati completi contiene l'elemento trovato per "più vicino" ed estrarre quei dati. Ma ancora una volta è solo "vicino" e non può mai restituire più di un risultato da un array.
Ma in generale è meglio solo separare gli oggetti come documenti nella propria collezione, dove la corrispondenza con un oggetto distinto è solo una questione di corrispondenza del documento. Quindi, con l'array sopra nella sua raccolta, emetti semplicemente la query per la geometria corrispondente:
db.shapes.find({
"geometry" : {
"$geoIntersects" : {
"$geometry" : {
"type" : "Polygon" ,
"coordinates" : [ [
[ -77.02877718955278 , -12.123750122669545],
[ -77.03457042574883 , -12.123750122669545],
[ -77.03457042574883 , -12.12736341792724],
[ -77.02877718955278 , -12.12736341792724],
[ -77.02877718955278 , -12.123750122669545]
]]
}
}
}
})
Che fornisce gli oggetti corretti poiché in questo caso la forma interseca entrambi:
{
"_id" : ObjectId("55f8d2fa66c2e7c750414b7a"),
"name" : "penta",
"geometry" : {
"type" : "Polygon",
"coordinates" : [[
[
-77.03228048980236,
-12.127106755278156
],
[
-77.03367926180363,
-12.125513343445087
],
[
-77.03264493495226,
-12.123914349525215
],
[
-77.030099183321,
-12.123825188450454
],
[
-77.02998653054237,
-12.126200075283254
],
[
-77.03228048980236,
-12.127106755278156
]
]]
}
}
{
"_id" : ObjectId("55f8d2fa66c2e7c750414b7b"),
"name" : "triangle",
"geometry" : {
"type" : "Polygon",
"coordinates" : [[
[
-77.03135680407286,
-12.126657349201809
],
[
-77.03257888555527,
-12.124696802237303
],
[
-77.03006532043219,
-12.124623375687444
],
[
-77.03135680407286,
-12.126657349201809
]
]]
}
}
Quindi puoi usare gli array ma puoi davvero abbinare solo il documento e non i singoli membri dell'array che facevano parte della corrispondenza, quindi questo restituirà ovviamente i documenti del corso nel suo insieme e dovresti capire quali membri corrispondono ai criteri nel codice client .
In un'altra nota, molti dei tuoi tentativi di query cercano di "scomporre" l'array di coordinate dell'oggetto in singoli elementi. Questo non è affatto supportato in quanto l'oggetto può essere trattato solo nel suo insieme e non come parti "Punto".