mongodb geoSpatial query doesn't work - java

I'm trying to fetch records within a specific radius in km/miles.
mongodb 2d index:
db.collection.ensureIndex({locaction:"2d"})
a record in the collection has the indexed key:
"location" : { "longitude" : 34.791592164168, "latitude" : 32.0516908 0405 }
Calling collection's getIndexes() from shell gives me this:
...{
"v" : 1,
"key" : {
"location" : "2d"
},
"ns" : "events.events",
"name" : "location_2d"
}...
despite all the above, trying to fetch records with this command fails:
> db.events.find({location:{ $near :{ longitude:34,latitude:32},$maxDistance:10 / 3963.192}})
anyone can point out what prevent this from working?

AFAIK, $near takes an array of the two target values, so you can try giving your values in array: -
db.events.find({location:{ $near : [34, 32],$maxDistance:10 / 3963.192}})

Related

How to get a a property in a property from a dbobject in java, mongodb

So I have a few dbobjects in my mongo database. Here's an example of one of the objects:
{ "_id" : { "$oid" : "525b048580c3fb0d62d2b6fc"} , "city" : "London" , "currentWeather" : [ { "cloudcover" : "25" , "humidity" : "82" , "observation_time" : "08:37 PM" , "precipMM" : "0.0" , "pressure" : "1008" , "temp_C" : "11" , "temp_F" : "52" , "visibility" : "10" , "weatherCode" : "113" , "weatherDesc" : [ { "value" : "Clear"}] , "weatherIconUrl" : [ { "value" : "http://cdn.worldweatheronline.net/images/wsymbols01_png_64/wsymbol_0008_clear_sky_night.png"}] , "winddir16Point" : "W" , "winddirDegree" : "280" , "windspeedKmph" : "19" , "windspeedMiles" : "12"}]}
Now, I need to get all the dbobjects in my database whose value is lower than a given "temp_C", I have used something like this:
BasicDBObject query = new BasicDBObject("temp_C", new BasicDBObject("&gt", graden));
But it's failing, and I think it is because the property is a subproperty of "currentWeather", yet I have no idea how to address this problem. I am using java to do this.
Looking at your document structure, you're trying to access a subdocument that lives inside an array in your document, so it's a bit more complicated than a standard query:
{ "_id" : { "$oid" : "525b048580c3fb0d62d2b6fc"} , <-- Document
"city" : "London" ,
"currentWeather" : [ <-- Array
{ "cloudcover" : "25", <-- Sub document
...etc...
"pressure" : "1008" ,
"temp_C" : "11",
"temp_F" : "52",
...etc...
}
]
}
In order to get to the nested object, you need to reference its position in the array (in this case, it's zero as it's the first element in the array) and then the field name in the sub document. So your query looks like this:
BasicDBObject query = new BasicDBObject("currentWeather.0.temp_C",
new BasicDBObject("$gt", 11));
Note you had two problems in your original query:
1) You need to reference currentWeather.0.temp_C
2) Your gt operator needs to start with a dollar sign not an ampersand.
Also, you said you wanted the query to return values lower than a given value, in which case you probably want $lt not $gt.
You can't directly use the value of the object of an array in a query. You can use aggregate framework of Mongo. Java Docs For Aggregate are here

Mongo query inside Hashmap with unknown hash key

Platform: MongoDB, Spring, SpringDataMongoDB
I have a collection called "Encounter" with below structure
Encounter:
{ "_id" : "49a0515b-e020-4e0d-aa6c-6f96bb867288",
"_class" : "com.keype.hawk.health.emr.api.transaction.model.Encounter",
"encounterTypeId" : "c4f657f0-015d-4b02-a216-f3beba2c64be",
"visitId" : "8b4c48c6-d969-4926-8b8f-05d2f58491ae",
"status" : "ACTIVE",
"form" :
{
"_id" : "be3cddc5-4cec-4ce5-8592-72f1d7a0f093",
"formCode" : "CBC",
"fields" : {
"dc" : {
"label" : "DC",
"name" : "tc",
},
"tc" : {
"label" : "TC",
"name" : "tc",
},
"notes" : {
"label" : "Notes",
"name" : "notes",
}
},
"notes" : "Blood Test",
"dateCreated" : NumberLong("1376916746564"),
"dateModified" : NumberLong("1376916746564"),
"staffCreated" : 10013,
"staffModified" : 10013
},
}
The element "fields" is represented using a Java Hashmap as:
protected LinkedHashMap<String, Field> fields;
The Key to the hashmap () is not fixed, but generated at run time.
How do I query to get all documents in the collection where "label" = "TC"?
It's not possible to query like db.encounter.find({'form.fields.dc.label':'TC'}) because the element name 'dc' is NOT known. I want to skip that postion and the execute query, something like:
db.encounter.find({'form.fields.*.label':'TC'});
Any ideas?
Also, how do I best use indexes in this scenario?
If fields were an array and your key a part of the sub-document instead:
"fields" : [
{ "key" : "dc",
"label" : "DC",
"name" : "dc"
},
{ "key" : "tc",
"label" : "TC",
"name" : "tc"
}
]
In this case, you could simply query for any sub-element inside the array:
db.coll.find({"form.fields.label":"TC"})
Not sure how you would integrate that with Spring, but perhaps the idea helps? As far as indexes are concerned, you can index into the array, which gives you a multi-key index. Basically, the index will have a separate entry pointing to the document for each array value.

Error retrieving using date query in mongodb from Grails gmongo

I have a string as:
'"startDate" : {"\\$gte" : new Date() }'
I actually want to query my mongodb database collection for all the collections with dates after the present date.Here is a sample document:
{
"_id" : ObjectId("51e2a857adc0c2fb535f6904"),
"dateInfo" : {
"dates" : {
"startDate" : ISODate("2013-07-13T04:00:00Z"),
"endDate" : ISODate("2013-07-19T20:00:00Z")
},
"named" : "name1",
"fieldX" : "field1",
"contact" : {
"numbs" : ["+44 121 127 127", "+44 568 789 256", "+44 687 5788 9875"]
}
},
"Locality" : "locality1",
"type" : "ewhet"
}
from mongo shell, I am able to query it as follows:
db.collectionName.find({"dateInfo.dates.startDate" : {"$gte" : new Date()}})
Now I want to do it from groovy. I am trying to do it as(using mongoDB java api):
DBCursor cursor = db.collectionName.find(new JsonSlurper().parseText('{"startDate" : {"\$gte" : new Date() }}'))
Above code gives error as:
Lexing failed on line: 1, column: 48, while reading 'new ', was trying to match the constant 'null'
Now the problem with JsonSlurper is that it requires double quotes in both key and value names.But in case I put a double quote in new Date(), it wont be evaluated by mongodb.
So what can be done here?
Have you tried:
db.collectionName.find( [ 'dateInfo.dates.startDate' : ['$gte' : new Date() ] ] )

morphia : upsert on Object embedded in an array

Using Morphia, is it possible to perform a saveOrUpdate / upsert operation on an object embedded inside an array.
Consider the following document :
{
_id : "abcd",
myArray : [{
"key" : "areaTotal",
"value" : "101.9",
"label" : "Total area (municipality)"
}, {
"key" : "areaUrban",
"value" : "803",
"label" : "Total area (urban)"
}, {
"key" : "populationDensity",
"value" : "15991",
"label" : "Population desnsity"
}
]
}
Is there a clean way to replace for example array element with key "areaUrban" by another object
such as
{
"key" : "areaUrban",
"value" : "123",
"label" : "a new label"
}
For now I do it in two update operations first delete, then add :
UpdateOperations<T> ops = createUpdateOperations().removeAll("myArray ", new BasicDBObject("key", "areaUrban"));
update(createQuery().field("_id").equal(myObjId),ops);
UpdateOperations<T> ops2 = createUpdateOperations().add("myArray ", myReplacementObject);
update(createQuery().field("_id").equal(myObjId),ops2);
Which works fine but can I do it in only one update op (either with morphia or with plain mongo java driver) ?
Also if a matching object did not originally exist in the array, then the myReplacementObject object should just be added to the array.
thanks
With the $ positional operator:
db.test.update({_id: "abcd", "myArray.key": "areaUrban"}, {$set: {"myArray.$.value": 123, "myArray.$.label": "a new label"}})
[Edit] As JohnnyHK mentions in the comments this won't upsert the nested document if it doesn't exist.

MongoDB $near query using Java driver

I have some shops with products on them in my MongoDB db following this data model:
Shop
{
idShop, name, location {lat, lon}, products [] of int
}
If I run the following command in the mongoDB default console:
db.shops.find({products:1, location:{$near:[41.391204,2.145381]}}).limit(300)
to find the shops that have product nÂș 1 ordered by distance I get the following results:
{ "_id" : ObjectId("4f410cefe4b03a0e3cff6f5a"), "name" : "Shop1", "location" : { "lat" : 41.389915, "lon" : 2.135628 }, "products" : [ 1, 5, 4 ] }
{ "_id" : ObjectId("4f410cefe4b03a0e3cff6f59"), "name" : "Shop2 Center", "location" : { "lat" : 41.388191, "lon" : 2.128816 }, "products" : [ 1, 2, 3 ] }
{ "_id" : ObjectId("4f410cefe4b03a0e3cff6f5c"), "name" : "Shop3", "location" : { "lat" : 41.384712, "lon" : 2.172031 }, "products" : [ 6, 1 ] }
{ "_id" : ObjectId("4f410cefe4b03a0e3cff6f5d"), "name" : "Shop4", "location" : { "lat" : 41.384029, "lon" : 2.173936 }, "products" : [ 6, 1, 2, 3, 4, 5 ] }
Now, I want the same results but using my java servlet. If I search by only product number, the results are OK but not sorted. Then, if I try to sort them by adding a new key/value condition it doesn't return nothing. The code I'm using is the following:
BasicDBObject query = new BasicDBObject();
query.put("products", Integer.parseInt(idProduct));
QueryBuilder query2 = new QueryBuilder();
query2.near(Double.parseDouble(lat), Double.parseDouble(lon));
query.putAll(query2.get());
curShops = collShops.find(query);
This returns an empty JSON. I've also tryed other ways like:
BasicDBObject query = new BasicDBObject();
query.put("products", Integer.parseInt(idProduct));
ArrayList ar = new ArrayList(2);
ar.add(Double.parseDouble(lat));
ar.add(Double.parseDouble(lon));
query.put("location", new BasicDBObject("$near", ar));
curShops = collShops.find(query);
Without any luck.
Can anyone help me with this?
Thanks in advance.
I dont have any experience with java driver, but it seem to me the problem is in this line
query2.near(Double.parseDouble(lat), Double.parseDouble(lon));
Accoridng to mongodb documentation,
The code assumes that you are using decimal degrees in (longitude,
latitude) order. This is the same order used for the GeoJSON spec.
Using (latitude, longitude) will result in very incorrect results, but
is often the ordering used elsewhere, so it is good to double-check
Also from the java mongodb-api-doc, you can see
near
public QueryBuilder near(double x,
double y)
Equivalent of the $near operand
Parameters:
x - x coordinate
y - y coordinate
x-cordinate denotes Longitude here. So the location co-ordinates must be passed as [lon,lat] instead [lat,lon]
Change your query to
query2.near(Double.parseDouble(lon), Double.parseDouble(lat));
to make it work
Yes, this is pretty straight forward. I have just posted an example that should walk you through the solution at http://chuckjohnson.wordpress.com/ - see http://chuckjohnson.wordpress.com/2012/04/02/geospatial-location-based-searches-in-mongodb-part-2-simple-searching/

Categories

Resources