C'est l'une de ces questions à répondre par oui et par non, car oui, un tableau est pris en charge pour la correspondance des résultats, mais ce n'est probablement pas non plus ce que vous voulez vraiment compte tenu des restrictions sur la façon dont la correspondance est effectuée.
Le changement notable dont vous avez besoin ici est que les objets eux-mêmes ne sont pas définis de manière à ce que MongoDB les reconnaisse tels que vous les avez actuellement formés. Il existe deux formulaires d'index et de recherche générale, soit avec des paires de coordonnées héritées (qui sont juste un point x, y), soit sous la forme GeoJSON avec les objets GeoJSON pris en charge. Votre problème est que vous avez un format GeoJSON "psuedo" qui n'est pas vraiment conforme à la spécification, et que vous essayez d'accéder directement aux "coordonnées", où vous avez besoin d'un objet de niveau supérieur comme celui-ci :
{
"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
]
]]
}
}
]
}
Cela résume donc la partie GeoJSON pour qu'elle soit à la fois bien formée et séparée des autres métadonnées qui ne font pas partie de la spécification. Idéalement, vous indexeriez également, bien que ce ne soit pas obligatoire pour $geoWithin
ou $geoIntersects
cela aide certainement :
db.regions.createIndex({ "regions.geometry": "2dsphere" })
Définir le chemin complet vers la définition GeoJSON dans l'élément de tableau.
Ensuite, les requêtes fonctionnent correctement :
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]
]]
}
}
}
})
Ce qui correspond au document ci-dessus. Mais bien sûr, il y a plusieurs objets dans le tableau, donc la question est, lesquels correspondent ? À laquelle il n'y a pas de réponse prise en charge, car MongoDB correspond au "document" et n'indique en aucune façon quel élément de tableau a été mis en correspondance.
Il y a une option dans l'agrégation $geoNear
cela permet de renvoyer l'objet correspondant, où dans ce cas il serait "le plus proche". Et avec des détails comme celui-ci, il est alors possible d'utiliser ces informations pour faire correspondre quel élément de tableau avec des métadonnées complètes contient l'élément qui a été trouvé pour "le plus proche" et extraire ces données. Mais encore une fois, il est "proche" uniquement et ne peut jamais renvoyer plus d'un résultat à partir d'un tableau.
Mais d'une manière générale, il est préférable de séparer uniquement les objets en tant que documents dans leur propre collection, où la correspondance avec un objet distinct consiste simplement à faire correspondre le document. Ainsi, avec le tableau ci-dessus dans sa propre collection, il vous suffit d'émettre la requête pour la géométrie correspondante :
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]
]]
}
}
}
})
Ce qui donne le ou les objets corrects car dans ce cas, la forme coupe les deux :
{
"_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
]
]]
}
}
Vous pouvez donc utiliser des tableaux, mais vous ne pouvez vraiment faire correspondre le document et non les membres individuels du tableau qui faisaient partie de la correspondance, donc cela renverra bien sûr les documents dans leur ensemble et vous devrez déterminer quels membres correspondent aux critères dans le code client .
Sur une autre note, plusieurs de vos tentatives de requête cherchent à "diviser" le tableau de coordonnées de l'objet en éléments individuels. Ceci n'est pas du tout pris en charge car l'objet ne peut être traité que dans son ensemble et non comme ses parties "Point".