Cant create 2dsphere index in mongoDB - mongodb

When I try to create 2dsphere index in mongoDB i get this error msg:
> db.mahalle.createIndex({geometry:"2dsphere"})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"errmsg" : "exception: Can't extract geo keys: { _id: ObjectId('55b4e025a6ef7e9c50ae79cd'), type: \"Feature\", p
roperties: { ADI: \"Çelemli\", ILADI: \"Adana\", ILCEADI: \"Yüre?ir\", BUCAKADI: \"Merkez\", KOYADI: \"Çelemli\", ILKOD:
1 }, geometry: { type: \"Polygon\", coordinates: [ [ [ 35.624498, 36.849395 ], [ 35.649357, 36.876937 ], [ 35.657724, 3
6.879572 ], [ 35.663334, 36.873718 ], [ 35.668063, 36.875857 ], [ 35.671228, 36.87511 ], [ 35.676613, 36.872193 ], [ 35.
676789, 36.86627 ], [ 35.681188, 36.865075 ], [ 35.683002, 36.864582 ], [ 35.685911, 36.858289 ], [ 35.690937, 36.856315
], [ 35.698809, 36.857084 ], [ 35.70811, 36.84059 ], [ 35.703934, 36.838901 ], [ 35.669599, 36.82501 ], [ 35.65748, 36.
820107 ], [ 35.63049, 36.809188 ], [ 35.639549, 36.812853 ], [ 35.625102, 36.834434 ], [ 35.624498, 36.849395 ] ] ] } }
Loop is not valid: [ [ 35.624498, 36.849395 ], [ 35.649357, 36.876937 ], [ 35.657724, 36.879572 ], [ 35.663334, 36.8737
18 ], [ 35.668063, 36.875857 ], [ 35.671228, 36.87511 ], [ 35.676613, 36.872193 ], [ 35.676789, 36.86627 ], [ 35.681188,
36.865075 ], [ 35.683002, 36.864582 ], [ 35.685911, 36.858289 ], [ 35.690937, 36.856315 ], [ 35.698809, 36.857084 ], [
35.70811, 36.84059 ], [ 35.703934, 36.838901 ], [ 35.669599, 36.82501 ], [ 35.65748, 36.820107 ], [ 35.63049, 36.809188
], [ 35.639549, 36.812853 ], [ 35.625102, 36.834434 ], [ 35.624498, 36.849395 ] ] Edges 16 and 18 cross. Edge locations
in degrees: [35.6574800, 36.8201070]-[35.6304900, 36.8091880] and [35.6395490, 36.8128530]-[35.6251020, 36.8344340]",
"code" : 16755,
"ok" : 0
}
>
collection data looks like this:
> db.mahalle.findOne()
{
"_id" : ObjectId("55b4e025a6ef7e9c50ae792f"),
"type" : "Feature",
"properties" : {
"KOYADI" : "Ömerli",
"ILKOD" : 1,
"ADI" : "Ömerli",
"ILADI" : "Adana",
"ILCEADI" : "Pozanty",
"BUCAKADI" : "Merkez"
},
"geometry" : {
"type" : "Polygon",
"coordinates" : [
[
[
34.840791,
37.516416
],
[
34.843066,
37.525614
],
[
34.847284,
37.545556
],
[
34.849961,
37.602446
],
[
34.892618,
37.570159
],
[
34.8991,
37.559108
],
[
34.902859,
37.545415
],
[
34.887897,
37.508253
],
[
34.843046,
37.489936
],
[
34.842049,
37.501638
],
[
34.840791,
37.516416
]
]
]
}
}
I have to create 2dsphere index in order to search coordinate in Polygonal areas. How can i fix this? Thanks

Related

MongoDB can't parse query (2dsphere): two conditions

I have the following object in my Collection:
{
"_id":"test123",
"footprint":{
"type":"Polygon",
"coordinates":[
[
[10, 30], [20, 45], [38, 38], [43, 38], [45, 30], [10, 30]
]
]
}
}
with index of type "2dsphere" on "footprint" attribute.
Now, I would like to implements the geospatial query "overlaps", as implemented by ST_Overlaps in PostGIS: https://postgis.net/docs/ST_Overlaps.html.
Due to the fact that MongoDB doesn't support "overlap" natively (only within, intersect and near) and according to the above definition, I whould return all overlapping documents not totally within the search area.
Therefore, I'm trying to execute the following filter:
{
"footprint":{
"$geoIntersects":{
"$geometry":{
"type":"Polygon",
"coordinates":[
[
[
41.62109375000001,
38.087716380862716
],
[
41.870727539062514,
37.998201197578084
],
[
41.72393798828124,
38.01268326428104
],
[
41.62109375000001,
38.087716380862716
]
]
]
}
},
"$not":{
"$geoWithin":{
"$geometry":{
"type":"Polygon",
"coordinates":[
[
[
41.62109375000001,
38.087716380862716
],
[
41.870727539062514,
37.998201197578084
],
[
41.72393798828124,
38.01268326428104
],
[
41.62109375000001,
38.087716380862716
]
]
]
}
}
}
}
}
But I get the following error:
can't parse extra field: $not: { $geoWithin: { $geometry: { type: "Polygon", coordinates: [ [ [ 41.62109375000001, 38.08771638086272 ], [ 41.87072753906251, 37.99820119757808 ], [ 41.72393798828124, 38.01268326428104 ], [ 41.62109375000001, 38.08771638086272 ] ] ] } } }
After several tests, it seems I can't execute a second filter on the same attribute.
Am I wrong? Is there any workaround?
Thanks
This is due to the query language and how it parses objects, the object you're trying to use looks like this:
{ key: { query1, query2 }}
Where query1 is $geoIntersects and query2 is $not which is just not a valid structure, what you can do is wrap both of them with an $and query like so:
{
$and: [
{
"footprint": {
"$geoIntersects": {
"$geometry": {
"type": "Polygon",
"coordinates": [
[
[
41.62109375000001,
38.087716380862716
],
[
41.870727539062514,
37.998201197578084
],
[
41.72393798828124,
38.01268326428104
],
[
41.62109375000001,
38.087716380862716
]
]
]
}
}
}
},
{
footprint: {
"$not": {
"$geoWithin": {
"$geometry": {
"type": "Polygon",
"coordinates": [
[
[
41.62109375000001,
38.087716380862716
],
[
41.870727539062514,
37.998201197578084
],
[
41.72393798828124,
38.01268326428104
],
[
41.62109375000001,
38.087716380862716
]
]
]
}
}
}
}
}
]
}

Geospatial Query in MongoDB to Return Documents which contain a specified Point (Longatude, Latitude)

I am attempting to create a query that will return all documents which have a polygon or LineString which contains a point on the longitude,latitude coordinate system. Can anyone help me to pinpoint the issue with my query? I have tried to troubleshoot this for quite a while and my query appears to follow the mongo 2.6.5 documentation.
So far, considering a document which is in the vendor collection may be defined as follows:
{ "VENDOR": "LUIGIS HARDWARE STORE", "AREA_ON_EARTH_THAT_SHOP_SERVICES": { "type": "LineString", "coordinates": [ [ -73.987792968875, 40.728235015886916 ], [ -73.98737335280508, 40.71806335844922 ], [ -73.986816840625, 40.72778488158918 ], [ -73.98597718728516, 40.71747858911133 ], [ -73.98331451418602, 40.726640847241214 ], [ -73.98307800292969, 40.71710968017578 ], [ -73.9828872680664, 40.71734619140625 ], [ -73.98235321044922, 40.718345642089844 ], [ -73.98203751708984, 40.729120025634764 ], [ -73.98183781738281, 40.719478607177734 ], [ -73.9813332421875, 40.720550537109375 ], [ -73.98103095458984, 40.72093963623047 ], [ -73.9805679321289, 40.72159957885742 ], [ -73.98014068603516, 40.72217559814453 ], [ -73.97969055175781, 40.722801208496094 ], [ -73.97838592529297, 40.72460174560547 ], [ -73.97750091552734, 40.72579574584961 ], [ -73.97659301757812, 40.72700500488281 ], [ -73.97615814208984, 40.7276725769043 ], [ -73.97564697265625, 40.72834014892578 ], [ -73.9739761352539, 40.734655670166016 ], [ -73.9738998413086, 40.73478918457031 ], [ -73.97396087646484, 40.7410791015625 ], [ -73.9742660522461, 40.732242584228516 ], [ -73.97443389892578, 40.732810974121094 ], [ -73.97505950927734, 40.735130310058594 ], [ -73.9751205444336, 40.735748291015625 ], [ -73.9751205444336, 40.73612976074219 ], [ -73.97500610351562, 40.73664855957031 ], [ -73.97478485107422, 40.737037658691406 ], [ -73.97380828857422, 40.73845291137695 ], [ -73.97335815429688, 40.73912811279297 ], [ -73.9732437133789, 40.73942947387695 ], [ -73.97313690185547, 40.73974609375 ], [ -73.97337341308594, 40.73988342285156 ], [ -73.97344970703125, 40.7398681640625 ], [ -73.97357940673828, 40.73987579345703 ], [ -73.97401428222656, 40.74009704589844 ], [ -73.97419738769531, 40.740135192871094 ], [ -73.97447967529297, 40.74012756347656 ], [ -73.97579956054688, 40.74070358276367 ], [ -73.98030090332031, 40.742591857910156 ], [ -73.9834213256836, 40.74393081665039 ], [ -73.9886245727539, 40.74612045288086 ], [ -73.9901123046875, 40.74671173095703 ], [ -73.99053955078125, 40.74614334106445 ], [ -73.99099731445312, 40.7454948425293 ], [ -73.99236297607422, 40.7436408996582 ], [ -73.99419403076172, 40.741111755371094 ], [ -73.9954833984375, 40.739356994628906 ], [ -73.99685668945312, 40.73744583129883 ], [ -73.99828338623047, 40.7354850769043 ], [ -74.0000991821289, 40.74301315307617 ], [ -74.0005874633789, 40.74229217529297 ], [ -74.0009994506836, 40.74176956176758 ], [ -74.00108337402344, 40.74163986206055 ], [ -74.00177001953125, 40.7305908203125 ], [ -74.00286865234375, 40.72846984863281 ], [ -74.00321197509766, 40.72770690917969 ], [ -74.00350952148438, 40.72700500488281 ], [ -74.00405883789062, 40.72560119628906 ], [ -74.00466918945312, 40.724159240722656 ], [ -74.0048828125, 40.72370529174805 ], [ -74.00494384765625, 40.723575592041016 ], [ -74.00322723388672, 40.72327423095703 ], [ -74.00308227539062, 40.7332666015625 ], [ -74.00252532958984, 40.72303009033203 ], [ -73.9991455078125, 40.721378326416016 ], [ -73.99333679199219, 40.72102355957031 ], [ -73.99387902832031, 40.721527099609375 ], [ -73.9933373413086, 40.72134780883789 ], [ -73.99390356445312, 40.72053527832031 ], [ -73.99302673339844, 40.71986770629883 ], [ -73.99363110351562, 40.7191276550293 ], [ -73.98379296875, 40.71823501586914 ] ] } }
Given this, I am trying the following query which fails:
db.vendors.find({ AREA_ON_EARTH_THAT_SHOP_SERVICES : { $geoWithin: { $geometry: { type: "Point", coordinates: [ -73.997439,40.730823]
} } } })
Which results in error:
error: {
"$err" : "$within not supported with provided geometry: { $geoWithin: { $geometry: { type: \"Point\", coordinates: [ -73.997439,40.730823 ] } } }",
"code" : 16672
}
The shape operator cannot be "Point". The available shape operators are: $box, $polygon, $center and $centerSphere.
You can use $center in this case:
{
"AREA_ON_EARTH_THAT_SHOP_SERVICES": {
$geoWithin: { $center: [ [ <x>, <y> ] , <radius> ] }
}
}
You query then should be like this, note that 10 is the radius that makes the circle from center cover entirely the polygone:
db.vendors.find({ "AREA_ON_EARTH_THAT_SHOP_SERVICES" :
{ $geoWithin: { $center: [ [ -73.98652, 40.752044 ], 10 ] } }
})
Or you can use $geoIntersects with "Point", if that gives you the expected result:
db.vendors.find({ "AREA_ON_EARTH_THAT_SHOP_SERVICES" : { $geoIntersects:
{ $geometry: { type: "Point", coordinates: [ -73.98652, 40.752044 ]
} } } })
I faced pretty much the same issue, and got a working example by:
db.getCollection('places').insert({
id: 'some square from 0,0 to 10,10',
loc: {
type: "Polygon",
coordinates: [ [ [ 0 , 0 ] , [ 0 , 10 ] , [ 10 , 10 ] , [ 10 , 0 ], [ 0 , 0 ] ] ]
}
})
Then create index by loc field:
db.getCollection('places').createIndex( { loc : "2dsphere" } )
and then using $geoIntersects and $geometry type Point:
db.getCollection('places').find(
{
loc: {
$geoIntersects: {
$geometry: {
type : "Point" ,
coordinates:
[
1, 1
]
}
}
}
}
)

Mongodb sphere2d query

Hi i have an collection which contains this object
{
"_id":"53b0807ca004f2ad5f0c9839",
"id":"3427734",
"version":"4",
"timestamp":"2012-08-04T12:06:46Z",
"changeset":"12608469",
"uid":"604523",
"user":"673a",
"fenced":"yes",
"landuse":"cemetery",
"name":"Friedhof St. Peter (Alter Friedhof)",
"poly":{
"type":"Polygon",
"coordinates":[
[
[
8.6763586,
49.5531628
],
[
8.6765129,
49.553132
],
[
8.6763608,
49.5528116
],
[
8.6767028,
49.5527433
],
[
8.6765809,
49.5524866
],
[
8.6770135,
49.5524431
],
[
8.6784924,
49.5520942
],
[
8.6788149,
49.5521769
],
[
8.6789908,
49.5524369
],
[
8.6793862,
49.5525109
],
[
8.6786997,
49.5530378
],
[
8.6779331,
49.5531445
],
[
8.6769458,
49.5532933
],
[
8.6766567,
49.5533521
],
[
8.6764405,
49.5533353
],
[
8.6763586,
49.5531628
]
]
]
}
}
now i'm makeing a query
{
"poly":{
$geoIntersects:{
$geometry:{
"type":"Polygon",
"coordinates":[
[
[
-180.0,
90.0
],
[
180.0,
90.0
],
[
180.0,
-90.0
],
[
-180.0,
-90.0
],
[
-180.0,
90.0
]
]
]
}
}
}
}
but it does not return the object.. it returns nothing. Any ideas why?
The GeoJson object that you passed is not acceptable. I changed the query parameter a little bit and it now works. As you have already understood now that the GeoJson object should fit within one hemisphere. If you need some demonstration of the $geoIntersect functionality of MongoDB, you can run the following query and see that it gives your polygon in the results:
db.Test.find({
"poly":{
'$geoIntersects':{
'$geometry':{
"type": "Polygon",
"coordinates": [
[
[
8.6763586,
49.5531628
],
[
8.6788149,
49.5521769
],
[
8.6786997,
49.5530378
],
[
8.6763586,
49.5531628
],
[
8.6763586,
49.5531628
]
]
]
}
}
}
});
Seems that my query won't work, i found this in the docs:
http://docs.mongodb.org/manual/reference/operator/query/geoIntersects/
Note
Any geometry specified with GeoJSON to $geoIntersects queries, must fit within a single hemisphere. MongoDB interprets geometries larger than half of the sphere as queries for the smaller of the complementary geometries.
i can only query fopr the right hmisphere
{
"poly":{
$geoIntersects:{
$geometry:{
"type":"Polygon",
"coordinates":[
[
[
1.0,
90.0
],
[
180.0,
90.0
],
[
180.0,
-90.0
],
[
1.0,
-90.0
],
[
1.0,
90.0
]
]
]
}
}
}
}

MongoDB find polygon coordinates using single point and radius

I have a collection with many polygon coordinates, which represent the different areas.
What my objective is I will send a lat, long and radius in a mongodb query which should return the polygon coordinates that falls within circle area.
Polygon coordinates:
{
"_id" : "300",
"name" : "MeKesler",
"centroid" : [
0,
0
],
"type" : "cnbd_id",
"coords" : [
[
39.8620784017,
-86.14614844330004
],
[
39.8625395793,
-86.15442037579999
],
[
39.8593030353,
-86.156373024
],
[
39.8586935926,
-86.15669488909998
],
[
39.8534225112,
-86.15854024890001
],
[
39.850391456,
-86.1589050293
],
[
39.8511657057,
-86.1479830742
],
[
39.8511986523,
-86.14598751070002
],
[
39.856881704,
-86.14605188370001
],
[
39.8575241063,
-86.14605188370001
],
[
39.8620784017,
-86.14614844330004
]
]
}
My query:
db.collection.find({
"coords" : {
"$within" : {
"$center" : [
[ 39.863110, -86.168456],
2/69.1
]
}
}
})
Can anyone help on this?
I believe the problem is that your document is not valid geojson. The valid syntax for your polygon would be
{
"_id": "300",
"name": "MeKesler",
"centroid": {
type: "Point",
coordinates: [0, 0]
},
"type": "cnbd_id",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[39.8620784017, -86.14614844330004],
[39.8625395793, -86.15442037579999],
[39.8593030353, -86.156373024],
[39.8586935926, -86.15669488909998],
[39.8534225112, -86.15854024890001],
[39.850391456, -86.1589050293],
[39.8511657057, -86.1479830742],
[39.8511986523, -86.14598751070002],
[39.856881704, -86.14605188370001],
[39.8575241063, -86.14605188370001],
[39.8620784017, -86.14614844330004]
]
]
}
}
Also, you should consider creating a 2dsphere index on the geometry field.
Lastly, the geo query should use the $geoWithin operator, and run against the polygon, not against its coordinates.
db.collection.find({
"geometry" : {
"$geoWithin" : {
"$center" : [
[ 39.863110, -86.168456],
2/69.1
]
}
}
})

cypher option to return nodes as json objects?

I am using the Cypher ReST API. It returns 1 object with two name value pairs "columns" and "data". Is there a way to ditch the columns and have the nodes returned as objects instead of an array of arrays? More in line with this: http://bl.ocks.org/4062045#miserables.json
Here is what I get now:
curl -d #query --header "Content-Type:application/json" http://localhost:7474/db/data/cypher
{
"columns" : [ "source", "r_type", "target" ],
"data" : [ [ "Corn", "LIKES", "Parsley" ], [ "Corn", "LIKES", "Sunflowers" ],
[ "Corn", "LIKES", "Pumpkin" ], [ "Corn", "LIKES", "Peas" ], [ "Corn", "LIKES", "Beans" ],
[ "Corn", "HATES", "Tomato" ], [ null, null, null ], [ "Carrots", "LIKES", "Tomato" ],
[ "Carrots", "LIKES", "Peas" ], [ "Carrots", "LIKES", "Onions" ], ....
the query file:
{
"query" : "start n = node(*) match n -[r?]-> m return n.name? as source, type(r) as r_type, m.name? as target",
"params" : {
}
}
You could write a server plugin to achieve this. It would then be available via the REST API.