Mongodb query for nested document in java - java

I am new to Mongodb. I have the following dataset in mongodb.
{
"_id": {
"$oid": "563644f44b17ca12886440a9"
},
"data": [
{
"uid": 1,
"character": " ",
"unicode": 32,
"color": -7309587
},
{
"uid": 2,
"character": "!",
"unicode": 33,
"color": -8911704
},
{
"uid": 3,
"character": "\"",
"unicode": 34,
"color": -1778539
}
I am trying to retrieve the color from this field using the _id and character. I am not able to execute the query.
This is what I tried.
DBObject clause1 = new BasicDBObject("_id",new ObjectId(KEY1));
DBObject clause2 = new BasicDBObject("data.character",text[i]);
BasicDBList or = new BasicDBList();
or.add(clause1);
or.add(clause2);
DBObject query = new BasicDBObject("$and", or);
Also I am having a lot of issues in finding ways to query in mongodb-java for the 3.0.0+ api. Could someone please help?

MongoClient mongoClient = new MongoClient(new ServerAddress("localhost", 27017));
MongoDatabase db = mongoClient.getDatabase("testDB");
AggregateIterable<Document> iterable = db.getCollection("testCollection").aggregate(
asList(new Document("$unwind", "$data"), new Document("$match", (new Document("_id", new ObjectId(
"5636f106b2acf98ecb033b98")).append("data.character", " "))), new Document("$project",
new Document("data.color", 1).append("_id", 0))));
iterable.forEach(new Block<Document>()
{
#Override
public void apply(final Document document)
{
System.out.println(document.toJson());
}
});
For more details check MongoDB Documentation.

A simple solution
In your document,
oid is an unique key for each document and hence your query should be like this
DBObject query = new BasicDBObject("_id.oid", KEY1);
// Query with value - DBObject query = new BasicDBObject("_id.oid","563644f44b17ca12886440a9");
Assign this to a cursor as shown below
DBCollection coll = db.getCollection("mycollection");
DBCursor cursor = coll.find(query);
Iterate the collection and retrieve your desired value.

Related

Spring Data MongoDB Aggregation return empty data but works on Compass with the same pipeline

I have a problem to query the mongoDB data. Here is the document:
{
productId:1,
warehouses:[
warehouseId:1,
productBatch:[
{
unitPrice:15.5,
quantity:1000,
expireSearchTimestamp:14145555545,
currentQuantity:50
},{
unitPrice:17.5,
quantity:1000,
expireSearchTimestamp:14145555545,
currentQuantity:50
}
]
]
}
and by code is
public List<ProductSearchResult> findCustomSearch(List<Integer> medicines,
List<Integer> warehousesIds, int quantity)
{
UnwindOperation unwind1 = Aggregation.unwind("warehouses");
UnwindOperation unwind2 = Aggregation.unwind("warehouses.productBatch");
ProjectionOperation project = Aggregation.project("warehouses.productBatch");
MatchOperation match = Aggregation.match(Criteria.where("productId").in(productIds)
.and("warehouses.warehouseId").in(warehousesIds)
.and("warehouses.productBatch.currentQuantity").gte(quantity));
SortOperation sort = Aggregation.sort(Direction.ASC, "productBatch.unitPrice");
LimitOperation limit = Aggregation.limit(3);
Aggregation aggregation = Aggregation
.newAggregation(unwind1, unwind2, project, sort, limit)
.withOptions(Aggregation.newAggregationOptions().allowDiskUse(true).explain(true)
.cursor(new BasicDBObject()).build());
AggregationResults<ProductSearchResult> results = mongoTemplate.aggregate(aggregation,
"medicine", ProductSearchResult.class);
List<ProductSearchResult> mappedResults = results.getMappedResults();
return mappedResults;
}
this is the function output
[
{
"$unwind": "$warehouses"
},
{
"$unwind": "$warehouses.productBatch"
},
{
"$match": {
"productId": {
"$in": [
20,
21
]
},
"warehouses.warehouse_id": {
"$in": [
1,
2,
3,
4,
5
]
},
"warehouses.productBatch.currentQuantity": {
"$gte": 10
}
}
},
{
"$project": {
"medicine_search": "$warehouses.productBatch"
}
},
{
"$sort": {
"productBatch.unitPrice": 1
}
},
{
"$limit": 3
}
]
when I run this function I got empty list but according to mongo compass I got 3 element.
thanks
I don't know why this block of code not work but the following one is satisfy for me
public void finalTry(List<Integer> productIds,
List<Integer> warehousesIds, int q, int limitN)
{
DBCollection collection = mongoTemplate.getCollection("product");
DBObject limit = new BasicDBObject("$limit", limitN);
DBObject sort = new BasicDBObject("$sort",
new BasicDBObject("productBatch.unitPrice", 1));
DBObject unwind1 = new BasicDBObject("$unwind", "$warehouses");
DBObject unwind2 = new BasicDBObject("$unwind", "$warehouses.productBatch");
DBObject project = new BasicDBObject("$project",
new BasicDBObject("productBatch", "$warehouses.productBatch"));
DBObject match1 = new BasicDBObject("$match",
new BasicDBObject("productId", new BasicDBObject("$in", productIds)));
DBObject match2 = new BasicDBObject("$match", new BasicDBObject("warehouses.warehouseId",
new BasicDBObject("$in", warehousesIds)));
DBObject match3 = new BasicDBObject("$match", new BasicDBObject(
"warehouses.productBatch.currentQuantity", new BasicDBObject("$gte", q)));
List<DBObject> pipeline = Arrays.asList(match1, unwind1, match2, unwind2, match3, project,
sort, limit);
AggregationOutput output = collection.aggregate(pipeline);
for (DBObject d : output.results())
{
System.out.println(d)
}
}
Thanks

Java query code for mongodb query

Can Some one help toconvert this mongo query into java code ?
It works fine in mongo command line ,but I am not able run this with java .
Here is mongo query
db.booking.aggregate([{
"$match": {
"bookingDate": {
"$ne": null,
"$gte": new Date("2017-04-01"),
"$lte": new Date("2018-03-31")
}
}
},
{
"$project": {
"totalAmount": 1,
"totalPax": 1,
"month": {
"$month": {
$add: ["$bookingDate", 25200000]
}
}
}
},
{
"$group": {
"_id": "$month",
"totalPax": {
"$sum": "$totalPax"
},
"totalAmount": {
"$sum": "$totalAmount"
},
}
}
])
This is what I have tried , but its not working ,
BasicDBObject match = new BasicDBObject("$match", new BasicDBObject("bookingDate",
new BasicDBObject("$gte", OperationsUtil.getISODateFromUIDate(startDate)).append("$lte",OperationsUtil.getISODateFromUIDate(endDate)).append("$ne", null)));
BasicDBObject match1 = new BasicDBObject("$match", new BasicDBObject("bookingDeleted",false));
BasicDBList add=new BasicDBList();
add.add(new BasicDBObject("$bookingDate",25200000));
BasicDBObject monthDoc=new BasicDBObject("$add",add);
BasicDBObject project = new BasicDBObject("$project",new BasicDBObject("_id",0).append("totalAmount",1).append("totalPax",1).append("month",new BasicDBObject("$month",monthDoc)));
DBObject group = new BasicDBObject("$group", new BasicDBObject("_id","$month")
.append("totalPaxCount", new BasicDBObject("$sum", "$totalPax")).append("totalAmount",new BasicDBObject("$sum", "$totalAmount")));
DBObject sort = new BasicDBObject("$sort", new BasicDBObject("_id", 1));
AggregationOutput cursor = bookingCollection.aggregate(match,match1,project,group,sort);
we were able to convert the above query solution , here is the code for the above query , just answering so that if someone come across this kind problem can refer this answer
BasicDBObject match = new BasicDBObject("$match", new BasicDBObject("bookingDate",
new BasicDBObject("$gte", OperationsUtil.getISODateFromUIDate(startDate)).append("$lte",OperationsUtil.getISODateFromUIDate(endDate)).append("$ne", null)));
BasicDBObject match1 = new BasicDBObject("$match", new BasicDBObject("bookingDeleted",false).append("tour.travelStatus",new BasicDBObject("$ne", "Unreceipted")));
BasicDBList addition=new BasicDBList();
addition.add("$bookingDate");
addition.add(OperationsConstant.UTC_TO_IST_MILLISECONDS);
BasicDBObject monthDoc=new BasicDBObject("$add",addition);
BasicDBObject project = new BasicDBObject("$project",new BasicDBObject("_id",0).append("totalAmount",1).append("totalPax",1).append("month",new BasicDBObject("$month",monthDoc)));
DBObject group = new BasicDBObject("$group", new BasicDBObject("_id","$month")
.append("totalPaxCount", new BasicDBObject("$sum", "$totalPax")).append("totalAmount",new BasicDBObject("$sum", "$totalAmount")));
DBObject sort = new BasicDBObject("$sort", new BasicDBObject("_id", 1));
AggregationOutput cursor = bookingCollection.aggregate(match,match1,project,group,sort);

How to update MongoDb database in Java?

I'm newbie with the MongoDb, there are a lot of examples about updating a collection in 2.x versions but I couldn't find any source about 3.x versions.
JAVA CODE:
MongoClient mongoClient = new MongoClient("localhost",27017);
MongoDatabase database = mongoClient.getDatabase("dbTest");
MongoCollection<Document> collection = database.getCollection("colTest");
Document updateQuery = new Document();
updateQuery.append("$set",
new Document().append("_id", "test"));
Document searchQuery = new Document();
searchQuery.append("likes", "125");
collection.updateMulti(searchQuery, updateQuery); //.updateMulti gives an error.
There isn't any updateMulti in 3.x so how can I check the id of the database and change one of the datas?
Example MongoDB:
{
"_id" : "test",
"status" : 2,
"time" : null,
"instagram" :{
"description" : "database",
"likes" : 100,
"url" : "http://www.instagram.com/",
"by", "users"
},
"batchid" : 15000234
}
Expected Output:
{
"_id" : "test",
"status" : 1,
"time" : null,
"instagram" :{
"description" : "database",
"likes" : 125,
"url" : "http://www.instagram.com/",
"by", "users"
},
"batchid" : 15000234
}
For Mongodb-java driver:
Use updateOne method
To update single Document within the collection based on the filter,
collection.updateOne(searchQuery, updateQuery );
Use updateMany method,
To Update multiple Documents within the collection based on the filter ,
collection.updateMany(searchQuery, updateQuery );
Example,
MongoClient client = new MongoClient("localhost",27017);
MongoDatabase db = client.getDatabase("TestDB");
MongoCollection<Document> collection = db.getCollection("test");
Document query = new Document();
query.append("_id","test");
Document setData = new Document();
setData.append("status", 1).append("instagram.likes", 125);
Document update = new Document();
update.append("$set", setData);
//To update single Document
collection.updateOne(query, update);
so i wrote this function
public void SetValueFromDB(String collectionName, String id, String id_value, String fieldOfChange, Object changToValue) {
MongoCollection<Document> collection = database.getCollection(collectionName);
BasicDBObject searchQuery = new BasicDBObject();
searchQuery.append(id, id_value);
Document setData = new Document();
setData.append(fieldOfChange, changToValue);
Document updateQuery = new Document();
updateQuery.append("$set", setData);
collection.updateOne(searchQuery, updateQuery);
}
so for use it
db.SetValueFromDB("MyCollection","_id","test","likes",150);

New aggregation feature with Mongo 3.2 driver, using Java

I want to perform an aggregation in Mongo 3.2 as explained here, but in Java:
https://docs.mongodb.org/master/reference/operator/aggregation/lookup/#pipe._S_lookup
At the moment my query object in java is very simple:
Document query = new Document();
query.append("employeId", employeId);
In addition to filtering by employeId, I would like to join this collection with company (where employee.company_id = company.id)
How can I do that in Java? It seems like I cannot find documentation of this new Mongo feature.
EDIT
Example of Employee collection:
{
"id" : 1,
"name" : "John",
"lastName" : "Moore",
"age" : 44,
"companyId": 10
}
Example of Company collection:
{
"id" : 10,
"companyName" : "Microsoft",
"numEmployee" : 100
}
Example of output expected
{
"id" : 1,
"name" : "John",
"lastName" : "Moore",
"companyId" : 10,
"companyName" : "Microsoft"
}
Running the following aggregation pipeline should give you the needed result
pipeline = [
{
"$match": {
"_id": employeeId
}
},
{
"$lookup": {
"from": "company",
"localField": "companyId",
"foreignField": "_id",
"as": "company"
}
},
{
"$project": {
"name": 1,
"lastName": 1,
"companyId": 1,
"companyName": "$company.companyName"
}
}
];
db.employee.aggregate(pipeline);
Java test implementation
public class JavaAggregation {
public static void main(String args[]) throws UnknownHostException {
MongoClient mongo = new MongoClient();
DB db = mongo.getDB("test");
DBCollection coll = db.getCollection("employee");
// create the pipeline operations, first with the $match
DBObject match = new BasicDBObject("$match",
new BasicDBObject("_id", employeeId)
);
// build the $lookup operations
DBObject lookupFields = new BasicDBObject("from", "company");
lookupFields.put("localField", "companyId");
lookupFields.put("foreignField", "_id");
lookupFields.put("as", "company");
DBObject lookup = new BasicDBObject("$lookup", lookupFields);
// build the $project operations
DBObject projectFields = new BasicDBObject("name", 1);
projectFields.put("lastName", 1);
projectFields.put("companyId", 1);
projectFields.put("companyName", "$company.companyName");
DBObject project = new BasicDBObject("$project", projectFields);
List<DBObject> pipeline = Arrays.asList(match, lookup, project);
AggregationOutput output = coll.aggregate(pipeline);
for (DBObject result : output.results()) {
System.out.println(result);
}
}
}

Pairs insertion/retrieval in/from field

I am trying to insert pairs in a mongoDB Document. This how i am doing it so far:
private static MongoCollection<Document> getCollectionn(String link, String coll){
...
}
public static void main(String[] args) {
MongoCollection<Document> fb_users;
fb_users = getCollectionn("mongodb://...", "fb_users2");
Document myDoc;
BasicDBObject query = new BasicDBObject();
query.put("fbid", "1");
myDoc = fb_users.find(query).first();
int postId=5;
int rating=3;
fb_users.updateOne(myDoc,
new Document("$push", new Document("ratings", java.util.Arrays.asList(rating, postId))));
Object a = myDoc.get("ratings");
ArrayList<Document> b = (ArrayList<Document>) a;
System.out.println(b.get(0);//prints [3, 5]
}
This is how the array document is inserted in the collection after two runs:
(the document already exists)
{
"_id": {
"$oid": "56f173b5e4b04eaac6531030"
},
"fbid": "1",
"ratings": [
[
3,
5
],
[
3,
5
]
]
}
In println i get the result [3, 5]
My question is this:
How can i recieve the numder 3 and the number 5 seperatly? Should i insert the documents with another way? Iam using mongo java driver 3.2.0.
Ok i found the solution. Here it is:
Document myDoc;
BasicDBObject query = new BasicDBObject();
query.put("fbid", "1");
myDoc = fb_users.find(query).first();
int postId=5;
int rating=3;
Document listItem = new Document("ratings", new Document(String.valueOf(rating), String.valueOf(postId)));
Document updateQuery = new Document("$push", listItem);
fb_users.updateOne(myDoc, updateQuery);
MongoCursor<Document> curs = fb_users.find(query).iterator();
ArrayList<Document> list = (ArrayList<Document>) myDoc.get("ratings");
Iterator<Document> iterateList = list .iterator();
while(iterateList .hasNext()){
Document pair = iterateList .next();
for(String element : pair.keySet()){
System.out.println(element + " " + pair.get(element));
}
}
and the json format is and should be like this:
{
"_id": {
"$oid": "56f173b5e4b04eaac6531030"
},
"fbid": "1",
"ratings": [
{
"3": "5"
},
{
"3": "5"
}
]
}

Categories

Resources