mongodb shell query with java - mongodb

How to write this mongodb shell query with using java?
query : db.building_feature.find({geometry : {$geoIntersects :{$geometry :{type : "Polygon", coordinates :[[[37.59777,55.73216],[37.59805,55.77615],[37.68710,55.77643],[37.68517,55.73290],[37.59777,55.73216]]]}}}})
My collection GeoSpatialIndex is "2dsphere".
My version which is not working :
DBCollection testCollection = db.getCollection("building_feature");
final LinkedList<double[]> geo = new LinkedList<>();
geo.addLast(new double[]{37.59777, 55.73216});
geo.addLast(new double[]{37.59805, 55.77615});
geo.addLast(new double[]{37.68710, 55.77643});
geo.addLast(new double[]{37.68517, 55.73290});
final BasicDBObject query
= new BasicDBObject("geometry", new BasicDBObject("$within", new BasicDBObject("$geometry", geo)));
System.out.println("Result Count : " + testCollection.find(query).count());
Thanks.

You should write exactly the same query in Java:
BasicDBObject polygon = new BasicDBObject("type", "Polygon");
polygon.put("coordinates", <myArray>);
BasicDBObject query = new BasicDBObject(
"geometry", new BasicDBObject(
"$geoIntersects", new BasicDBObject(
"$geometry", polygon
)
)
);
<myArray> being your triple-nested double[][][] geoJSON polygon coordinates array.
Btw, it could be more clear to read with a JSON string and then JSON.parse.
And I think $whithin operator does not exist in MongoDB...

Related

Cursor Error for MongoDB Java aggregation function

I am trying to fetch the data from the MongoDB to get the top 5 most liked products.
But I'm getting below error. (MongoDB version 3.2.21)
com.mongodb.MongoCommandException: Command failed with error 9: 'The 'cursor' option is required, except for aggregate with the explain argument' on server localhost:27017. The full response is { "ok" : 0.0, "errmsg" : "The 'cursor' option is required, except for aggregate with the explain argument", "code" : 9, "codeName" : "FailedToParse" }
DBObject groupFields = groupFields = new BasicDBObject("_id", 0);
groupFields.put("_id", "$productId");
groupFields.put("avgRating", new BasicDBObject("$avg", "$productRvR"));
groupFields.put("productModelName", new BasicDBObject("$push", "$productMN"));
DBObject group = new BasicDBObject("$group", groupFields);
DBObject projectFields = new BasicDBObject("_id", 0);
projectFields.put("productId", "$_id");
projectFields.put("avgRating", "$avgRating");
projectFields.put("productModelName", "$productModelName");
DBObject project = new BasicDBObject("$project", projectFields);
DBObject sort = new BasicDBObject();
sort.put("avgRating",-1);
DBObject orderby=new BasicDBObject("$sort",sort);
DBObject limit=new BasicDBObject("$limit",5);
AggregationOutput aggregate userReviews.aggregate(group,project,orderby,limit);
LinkedHashMap<String, String> mostLikedProductsMap = new LinkedHashMap<String, String>();
for (DBObject queryResult : aggregate.results()) {
BasicDBObject obj = (BasicDBObject) queryResult;
BasicDBList productModelName = (BasicDBList) obj.get("productModelName");
mostLikedProductsMap.put((String)productModelName.get(0),obj.getString("avgRating"));
}
return mostLikedProductsMap;

Mongo DB Java 3.x Driver - Group By Query

I'd like to learn how to implement group by query using Mongo DB Java 3.x Driver. I want to group my collection through the usernames, and sort the results by the count of results DESC.
Here is the shell query which I want to implement the Java equivalent:
db.stream.aggregate({ $group: {_id: '$username', tweetCount: {$sum: 1} } }, { $sort: {tweetCount: -1} } );
Here is the Java code that I have implemented:
BasicDBObject groupFields = new BasicDBObject("_id", "username");
// count the results and store into countOfResults
groupFields.put("countOfResults", new BasicDBObject("$sum", 1));
BasicDBObject group = new BasicDBObject("$group", groupFields);
// sort the results by countOfResults DESC
BasicDBObject sortFields = new BasicDBObject("countOfResults", -1);
BasicDBObject sort = new BasicDBObject("$sort", sortFields);
List < BasicDBObject > pipeline = new ArrayList < BasicDBObject > ();
pipeline.add(group);
pipeline.add(sort);
AggregateIterable < Document > output = collection.aggregate(pipeline);
The result I need is the count of documents grouped by username. countOfResults returns the total number of the documents the collection has.
You should try not to use old object (BasicDBObject) types with Mongo 3.x. You can try something like this.
import static com.mongodb.client.model.Accumulators.*;
import static com.mongodb.client.model.Aggregates.*;
import static java.util.Arrays.asList;
Bson group = group("$username", sum("tweetCount", 1));
Bson sort = sort(new Document("tweetCount", -1));
AggregateIterable <Document> output = collection.aggregate(asList(group, sort));

mongodb 3.2 java driver aggregation whith match on lookup

I wonder how to perform the aggregation $match on a $lookup collection with the java driver for mongodb 3.2. Here is the structure of the two collections i am working on :
coll_one:{
_id : ObjectId("hex_string"),
foreign_id : ObjectId("hex_string") **the id of coll_two**}
coll_two:{
_id : ObjectId("hex_string"),
actif : true,
closed : false }
The lookup on the two ids (coll_one.foreign_id & coll_two._id) seems to work fine. But when i specify a match on coll_two.actif = true, it returns an empty result.
This is the Java code i'am using :
Bson lookup = new Document("$lookup",
new Document("from", "coll_two" )
.append("localField", "foreign_id")
.append("foreignField", "_id")
.append("as", "look_coll"));
List<Bson> filters = new ArrayList<Bson>();
filters.add(lookup);
//here is the MATCH
filters.add(match(eq("look_coll.actif",true)));
DB().getCollection("coll_one").aggregate(filters);
Evrything works fine whene i remove the match section. I have tried so many combination of possibilities with no success at all !!!
Can any body tells me if this is possible ????
Add your $match request to a Document instance :
Bson match = new Document("$match",
new Document("look_coll.actif", true));
filters.add(match);
Here is a full example :
MongoClient mongoClient = new MongoClient("localhost");
MongoDatabase db = mongoClient.getDatabase("mydb");
Bson lookup = new Document("$lookup",
new Document("from", "coll_two")
.append("localField", "foreign_id")
.append("foreignField", "_id")
.append("as", "look_coll"));
Bson match = new Document("$match",
new Document("look_coll.actif", true));
List<Bson> filters = new ArrayList<>();
filters.add(lookup);
filters.add(match);
AggregateIterable<Document> it = db.getCollection("coll_one").aggregate(filters);
for (Document row : it) {
System.out.println(row.toJson());
}

mongodb java aggregate return empty result

i need to use mongodb java aggregate function to detect duplicated documents in collection, this is the query i ran from command line and it worked:
db.placements.aggregate(
{$group:{ "_id: "$campaign", total:{$sum:1}}},
{$match: {total: {$gt:2}}},
{$limit:10},
{$skip:0}
);
and this is the java code i wrote:
DBObject groupFields = new BasicDBObject("_id", "$campaign");
groupFields.put("total", new BasicDBObject("$sum", 1));
DBObject group = new BasicDBObject("$group", groupFields);
DBObject matchFields = new BasicDBObject("total", new BasicDBObject("$gt", 2));
DBObject match = new BasicDBObject("$match", matchFields);
collection.aggregate(match, group, new BasicDBObject("$skip", 0), new BasicDBObject("$limit", 10));
but it always return empty result. can anyone tell me what's wrong?

mongodb java to insert embedded document

I have a collection with embedded documents in it.
System
{
System_Info: ...,
Tenant: [
{
Tenant_Id: ...,
Tenant_Info: ...,
Prop_Info: ...
},
{
Tenant_Id: ...,
Tenant_Info: ...,
Prop_Info: ...
} ]
}
If I need to insert another tenant information like this
Tenant { Tenant_Id:2,Tenant_Info:"check",prop_info:"client"}.
whats the mongodb query to insert embedded documents? and how to do it using java?
Use the following code to insert into array :
BasicDBObject query = new BasicDBObject();
query.put( "System_Info", "...." );
BasicDBObject tenant = new BasicDBObject();
tenant.put("Tenant_Id", 2);
tenant.put("Tenant_Info", "check");
tenant.put("Prop_Info", "client");
BasicDBObject update = new BasicDBObject();
update.put("$push", new BasicDBObject("Tenant",tenant));
coll.update(query, update,true,true);
Are you trying to add another Tenant into the array? If so, you would want to create a DBObject representing the Tenant, and then $push it onto the array.
In Java, embedded documents are represented by DBObjects (of which BasicDBObject is a subclass). Here is an example of inserting an embedded document, from the docs:
http://www.mongodb.org/display/DOCS/Java+Tutorial#JavaTutorial-InsertingaDocument
Additionally, here is an example of using $push in Java:
Updating an array in MongoDB using Java driver
...and this is how to do it with mongo-driver version >= 3.1 (mine is 3.2.2):
Document tenant = new Document("Tenant_Id", 2)
.append("Tenant_Info", "check")
.append("Prop_Info", "client");
Bson filter = Filters.eq( "System_Info", "...." ); //get the parent-document
Bson setUpdate = Updates.push("Tenant", tenant);
coll.updateOne(filter, setUpdate);
Hope that helps someone.