Running custom mongodb queries in java - java

I want to run raw mongoDb queries using runCommand() which takes in BSON data.
Following is my code
MongoClient mongoClient = new MongoClient();
MongoDatabase database = mongoClient.getDatabase("MyDB");
MongoCollection<Document> collection = (MongoCollection<Document>)database.runCommand(??);
If my query is
db.mycol.find({"by":"tutorials point"}).
What should be BSON data that I have to pass inside runCommand() ? Is it only
{{"by":"tutorials point"}}
or
db.mycol.find({"by":"tutorials point"}).
And If instead of find() i have to use Insert() how to go about it ??

Find:
db.runCommand({
find: "mycol",
filter: { by: "tutorials point"}
})
Insert:
db.runCommand({
insert: "mycol",
documents: [ { _id: 1, foo: "bar"} ]
})
I think the easiest why to do it in java is to use Jongo (http://jongo.org/).
Syntax is very similar to mongo shell.
jongo.runCommand("{find: 'mycol', filter: { by: 'tutorials point'}}")

You can not do that.
First of all you need to get your collection
like : MongoCollection<Document> collection = database.getCollection("test");
Once you have the collection you can run the raw query by using the util import com.mongodb.util.JSON;
this would be an example that you want to do:
MongoClient mongoClient = new MongoClient();
MongoDatabase database = mongoClient.getDatabase("MyDB");
MongoCollection<Document> collection = database.getCollection("mycol");
String rawQuery = "{\"by\": \"tutorials point\"}";
DBObject query = (DBObject) JSON.parse(rawQuery);
collection.find(query);

Give example of how it work
this was my query
db.getCollection('Collection').aggregate([{
$unwind: '$somearray'
}, {
$match: {
_id: ObjectId("123456"),
'somearray.type': "blabla"
}
}, {
$project: {
'_id':0,
'name': '$somearray.name',
'phone': '$phone'
}
}])
This was my Java program that did the same as query
public MongoIterable < Document > GetList(String collectionName, String id) {
MongoClient mongoClient = new MongoClient();
MongoDatabase database = mongoClient.getDatabase("MyDB");
MongoCollection < Document > collection = database.getCollection("collectionName");
Document match = Document.parse("{_id: ObjectId('" + id + "'),'somearray.type': 'blabla'}");
Document project = Document.parse("{ $project: { _id: 0,'name': '$somearray.name'}, 'phone': '$phone'}");
MongoIterable < Document > output = collection.aggregate(Arrays.asList(Aggregates.unwind("$somearray"), Aggregates.match(match), project));
return output;
}

Related

Convert data strings into Date format using ISODate function during the insertion mongo query to java code

db.collection.find().forEach(function(element){
element.BOOKING_CREATED_DATE = ISODate(element.BOOKING_CREATED_DATE);
db.collection.save(element);
})
Please help to convert this query to DBobject type to run in spring boot
Finally found the answer
MongoClient mongo = new MongoClient();
DB db = mongo.getDB("datarepo");
DBCollection collection = db.getCollection("rawdata");
db.eval("db.rawdata.find( { BOOKING_CREATED_DATE : { $type : 2 } } ).forEach(function(element){" +
"element.BOOKING_CREATED_DATE = ISODate(element.BOOKING_CREATED_DATE);" +
"db.rawdata.save(element);})")

MongoDB with Java - GroupBy more one column

i am trying transfer the PostgreSQL for MongoDB using java.
I have the SQL
SELECT id_buyer, buyer, SUM(qtde)
FROM test.log
GROUP BY id_buyer, buyer
and my new code
MongoClient mongoClient = new MongoClient();
MongoDatabase db = mongoClient.getDatabase("teste");
MongoCollection<Document> coll = db.getCollection("log");
DBObject groupFields = new BasicDBObject();
groupFields.put("id_buyer", "$id_buyer");
groupFields.put("buyer", "$buyer");
AggregateIterable<Document> mongoCollectionList = coll.aggregate(
Arrays.asList(
Aggregates.group(groupFields, Accumulators.sum("qtde", "$qtde")),
Aggregates.project(fields(include("comprador", "Quantidade")))
));
MongoCursor<Document> mongoCursor = mongoCollectionList.iterator();
while (mongoCursor.hasNext()) {
System.out.println(mongoCursor.next().toJson());
}
result
{ "_id" : { "id_buyer" : 2, "buyer" : "COMPS" }, "qtde" : 16703 }
How do i remove "id_buyer" and "buyer" that is into "_id" ?
Tks
you try like this..
AggregateIterable<Document> mongoCollectionList = collection.aggregate(
Arrays.asList(
Aggregates.group(groupFields, Accumulators.sum("qtde", "$qtde")),
Aggregates.project(Projections.fields(Projections.include("qtde"),Projections.excludeId()))
));
I have tested the answer posted by Veeram and it worked perfectly for me.
This was his sugestion:
Aggregates.project(fields(excludeId(),
computed("id_buyer", "$_id.id_buyer"),
computed("buyer", "$_id.buyer"),
include("comprador", "Quantidade")));

How to get rid of the mongo IDs when converting a collection to json

I'm using the mongo java API to convert a collection to json:
MongoCollection<Document> coll = db.getCollection("day_EURUSD");
FindIterable<Document> fi = coll.find();
System.out.println(fi.first().toJson());
However the outcome still contains nongoDB 'clutter':
{ "_id" : { "$oid" : "565d90808b821237efdc39cb" }, "currencyPairs" : [{ "a....
How can I elegently get rid of _id and $oid so that i'm back to a 'normal' json?
Thanks
Try this:
MongoCollection<Document> coll = db.getCollection("day_EURUSD");
FindIterable<Document> fi = coll.find();
fi.forEach(new Block<Document>() {
#Override
public void apply(final Document document) {
// Suppress the DB Id column of the query result.
document.remove("_id");
}
});
...

Java/Grails - MongoDB aggregation 16MB buffer size limit

I am trying to run mongo db aggregate query from java, but buffer size is exceeding 16MB. Is there any way to adjust the buffer size or any other workaround. I do not have the option to create collection in mongo server side and also I do not have any mongo utility like mongo.exe or mongoExport.exe in my client system.
Here is little part of code
if (!datasetObject?.isFlat && jsonFor != 'collection-grid'){
//mongoPipeline = new AggregateArgs (Pipeline = pipeline, AllowDiskUse = true, OutputMode = AggregateOutputMode.Cursor)
output= dataSetCollection.aggregate(pipeline)
}else{
output= dataSetCollection.aggregate(project)
}
I have 100K records with 30 field. When I query for 5 fields for all 100K records I get result(Success). But when I make a query for 100K records with all fields its throwing below error.
Issue is when I am trying to access all documents from collection including all fields of document its exceeding 16Mb limit size.
Actual Error:
com.mongodb.CommandFailureException: { "serverUsed" : "127.0.0.1:27017" , "errmsg" : "exception: aggregation result exceeds maximum document size (16MB)" , "code" : 16389 , "ok" : 0.0
How to resolve this issue?
Using MongoDB-3.0.6
Note: GridFS is not suitable for my criteria. Because I need to retrieve all documents in one request not one document.
When running the aggregation you can tell mongo to return a cursor. With the new APIs in the 3.0 Java driver that would look like this:
// Assuming MongoCollection
dataSetCollection.aggregate(pipeline).useCursor(true)
You might also need to tell it to use disk space on the server rather than doing it all in memory:
// Assuming MongoCollection
dataSetCollection.aggregate(pipeline).useCursor(true).allowDiskUse(true)
If you're using an older driver (or the old API in the new driver) those two options would look like this:
// Assuming DBCollection
dataSetCollection.aggregate(pipeline, AggregationOptions.builder()
.allowDiskUse(true)
.useCursor(true)
.build())
.useCursor(true)
There are two options to resolve this issue
1) use of $out which creates new collection and write result, Which is not good idea because this process is time consuming and complex to implement.
public class JavaAggregation {
public static void main(String args[]) throws UnknownHostException {
MongoClient mongo = new MongoClient();
DB db = mongo.getDB("databaseName");
DBCollection coll = db.getCollection("dataset");
/*
MONGO SHELL :
db.dataset.aggregate([
{ "$match": { isFlat : true } },
{ "$out": "datasetTemp" }
])
*/
DBObject match = new BasicDBObject("$match", new BasicDBObject("isFlat", true));
DBObject out = new BasicDBObject("$out", "datasetTemp");
AggregationOutput output = coll.aggregate(match, out);
DBCollection tempColl = db.getCollection("datasetTemp");
DBCursor cursor = tempColl.find();
try {
while(cursor.hasNext()) {
System.out.println(cursor.next());
}
} finally {
cursor.close();
}
}
}
2. Use of allowDiskUse(true) is very simple to implement and not even time consuming.
public class JavaAggregation {
public static void main(String args[]) throws UnknownHostException {
MongoClient mongo = new MongoClient();
DB db = mongo.getDB("databaseName");
DBCollection coll = db.getCollection("dataset");
/*
MONGO SHELL :
db.dataset.aggregate([
{ "$match": { isFlat : true } },
{ "$out": "datasetTemp" }
])
*/
DBObject match = new BasicDBObject("$match", new BasicDBObject("isFlat", true));
def dbObjArray = new BasicDBObject[1]
dbObjArray[0]= match
List<DBObject> flatPipeline = Arrays.asList(dbObjArray)
AggregationOptions aggregationOptions = AggregationOptions.builder()
.batchSize(100)
.outputMode(AggregationOptions.OutputMode.CURSOR)
.allowDiskUse(true)
.build();
def cursor = dataSetCollection.aggregate(flatPipeline,aggregationOptions)
try {
while(cursor.hasNext()) {
System.out.println(cursor.next());
}
}
finally {
cursor.close();
}
}
For more see here and here

What is Java Mongo Criteria for the following request

I would like to use mongodb.core.query.Criteria for following request:
db.accounts.find({ "personalSettings.nickName" : "testNickName"})
My scheme of document is:
{
"_id" : ObjectId("5354de90ad9b0f6c60bef7ba"),
"personalSettings" : {
"avatar" : "http://127.0.0.1:8080/assets/samples/avatar.png",
"nickName" : "testNickName"
},
"userName" : "testUser#testDomain.com"
}
I've tried to use this:
Query query = new Query(Criteria.where("personalSettings.nickName").is("testNickName"));
but i got:
java.lang.IllegalArgumentException: [Assertion failed] - this argument is required; it must not be null
personalSettings is a Map of < String,String >
Thanks
#Override
public Account getAccountByNickName(String nickname, String accountsCollection) {
Criteria criteria = Criteria.where("personalSettings.nickName").is(nickname);
DBCollection coll = mongoOperation.getCollection(accountsCollection);
DBCursor dbCursor = coll.find(Query.query(criteria).getQueryObject());
DBObject dbobj = dbCursor.next();
Account account = (new Gson()).fromJson(dbobj.toString(), Account.class);
return account;
}
For now - only one way :)
Because MongoDB doesn't support searching in map by elemMatch and doesn't support searching by ongoTemplate/MongoOperation

Categories

Resources