J'ai donc fait un petit test. Voici les données dans ma collection géo:
{ "_id" : ObjectId("536093e9e3c1d506da48a079"), "loc" : [ 120, 110 ] }
{ "_id" : ObjectId("5360940be3c1d506da48a07a"), "loc" : { "lat" : 120, "lng" : 130 } }
{ "_id" : ObjectId("53609422e3c1d506da48a07b"), "loc" : { "latitude" : 120, "lngitude" : 140 } }
{ "_id" : ObjectId("5360942be3c1d506da48a07c"), "loc" : { "latitude" : 120, "lngitude" : 150, "time" : 133232004 } }
J'ai fait quelques erreurs de sorts pour vous assurer que le nom n'a pas d'importance.
Une fois que je construire index avec:
db.geo.ensureIndex({loc: "2d"});
Je peux maintenant trouver avec $ près de l'opérateur.
Comme décrit dans le 2d index doc:
Les valeurs du tableau peuvent être soit des tableaux, comme dans [55,5, 42,3], ou les documents incorporés, comme dans {lng: 55,5, Lat: 42.3}
Il s'avère que c'est OK quand il y a des champs supplémentaires dans l'objet. Tant que les 2 premières propriétés sont la longitude et la latitude. Et il donne le résultat correct:
rs0:PRIMARY> db.geo.find({loc: {$near: [120, 150]}});
{ "_id" : ObjectId("5360942be3c1d506da48a07c"), "loc" : { "latitude" : 120, "lngitude" : 150, "time" : 133232004 } }
{ "_id" : ObjectId("53609422e3c1d506da48a07b"), "loc" : { "latitude" : 120, "lngitude" : 140 } }
{ "_id" : ObjectId("5360940be3c1d506da48a07a"), "loc" : { "lat" : 120, "lng" : 130 } }
{ "_id" : ObjectId("536093e9e3c1d506da48a079"), "loc" : [ 120, 110 ] }
De plus, lorsque vous avez index 2d sur le terrain, il vous empêchera d'insérer des données non valides comme:
rs0:PRIMARY> db.geo.insert({loc: {str: "string", latitude: 120, lngitude: 140, time: 133232004}});
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 16804,
"errmsg" : "insertDocument :: caused by :: 16804 location object expected, location array not in correct format"
}
})
Cependant, comme index accepte toujours le 1er champ comme longitude et le 2ème champ comme latitude. Vos données ne semblent pas satisfaire à l'exigence.