How to use DBObject Query in distinct function of mongo template? - mongodb

i want to find distinct value of a field with some Query criteria. my code is..
public List searchservice(String th_type) {
Query query = new Query();
query.addCriteria(Criteria.where("th_type").regex(th_type));
List list = operations.getCollection("doclist").distinct("th_type", query);
return list;
}
in mongo template a distinct function is defined
mongoTemplate.getCollection(collection).distinct(key, query)
bu my code is giving error because i am using simple Query object instead of DBObject Query. how can i use DBObject Query here?

Use a BasicDBObject for this:
public List searchservice(String th_type) {
BasicDBObject dbObject = new BasicDBObject();
dbObject.append("th_type", th_type);
DBCollection dBCollection = operations.getCollection("doclist");
List list = dBCollection.distinct("th_type", dbObject);
return list;
}
UPDATE:
With regex:
BasicDBObject regexQuery = new BasicDBObject();
regexQuery.put("th_type", new BasicDBObject("$regex", th_type));
List list = operations.getCollection("doclist").distinct("th_type",regexQuery);

Related

Mongo 3.6.3 java driver aggregate hint - returns undefined field 'hint'

I am trying to pass a hint on an aggregate in MongoDB Java Driver 3.6.3. The aggregate API allows for adding a hint as in:
MongoCollection<Document> coll = database.getCollection("myCollection")
ArrayList<BasicDBObject> docList = new ArrayList<BasicDBObject>();
BasicDBObject hint = new BasicDBObject("$hint","reportjob_customerId_1_siiDocumentAttributes.deleted_1");
MongoCursor<Document> cursor = coll.aggregate(docList).hint(hint).allowDiskUse(batchContext.isAllowDiskUse()).iterator();
I've tried with $hint and hint, but Mongo always returns Command failed with error -1: 'unrecognized field 'hint'
How do I properly send the hint on the aggregate call?
Looks like there is no support to pass the index name directly to hint. So you have pass the index creation document to the hint which you can get by name and use key to get the index document.
MongoCollection<Document> coll = database.getCollection("myCollection");
Bson index = coll.listIndexes().into(new ArrayList<>()).stream().filter(item -> item.getString("name").equals("reportjob_customerId_1_siiDocumentAttributes.deleted_1")).findFirst().get().getString("key");
List<BasicDBObject> docList = new ArrayList<BasicDBObject>();
MongoCursor<Document> cursor = coll.aggregate(docList).hint(index).allowDiskUse(batchContext.isAllowDiskUse()).iterator();
Legacy driver had support for both index name and document.
MongoClient client = new MongoClient();
DB database = client.getDB("myDatabase");
DBCollection coll = database.getCollection("myCollection");
List<BasicDBObject> docList = new ArrayList<BasicDBObject>();
AggregationOptions options = AggregationOptions.builder().allowDiskUse(batchContext.isAllowDiskUse()).build();
DBCursor dbCursor = ((DBCursor) coll.aggregate(docList, options)).hint("reportjob_customerId_1_siiDocumentAttributes.deleted_1");
You can create a jira to have the option to pass index name in the new driver here

MongoDB deleting aggregated cells

I have a problem.
I have collection of documents like this:
{
id (not _id),
type,
number
}
And what I want to do is aggregate cells with specific type and minimum number for this type for every id and delete them from this collection. Basically, single id can have few different number for specific type and I want to delete Document with the lowest value.
I tried to aggregate it using Java Driver 3 and mongoshell but I stucked on constructing it.
You can take reference from something like this
List<DBObject> pipeline=new ArrayList<DBObject>();
DBObject match = new BasicDBObject("$match", new BasicDBObject("date", sdf.format(new Date())).append("country", country).append("operator", operator).append("server_ip", server_ip));
DBObject unwind = new BasicDBObject("$unwind", "$details");
DBObject match2 = new BasicDBObject("$match", new BasicDBObject("details.type", "application_health"));
DBObject sort = new BasicDBObject("$sort", new BasicDBObject("details.datetime", -1));
DBObject limit = new BasicDBObject("$limit", 1);
pipeline.add(match);
pipeline.add(unwind);
pipeline.add(match2);
pipeline.add(sort);
pipeline.add(limit);
AggregationOutput outputoutput = collection.aggregate(pipeline);

Java code for mongodb aggregation query

I am new to Java.
I checked few examples having aggregate usage.But still having few doubt.
db.employee.aggregate({$unwind: '$dp.fin.Record'},
{$match:{"dp.mon":"patch.metrics",'dp.fin.Record':{$exists:1}}},
{$group:{_id: '$dp.fin.Record', count:{$sum:1}}},
{$project:{count:'$count'}}, {$group:{_id:'Total
Count',total:{$sum:'$count'}}});
Can anybody help me writing java equivalent.
I have doubt how can we pass multiple matching condition as I have shown above.
I am trying like below
BasicDBObject unwind = new BasicDBObject("$unwind",
"$dp.fin.Record"); DBObject match = new BasicDBObject("$match", new
BasicDBObjectBuilder(""));
I think this will help:
DBObject unwind = new BasicDBObject("$unwind", "$dp.fin.Record");
DBObject match = BasicDBObjectBuilder.start().push("$match")
.add("dp.mon", "patch.metrics")
.push("dp.fin.Record").add("$exists", true).get();
DBObject group1 = BasicDBObjectBuilder.start().push("$group")
.add("_id", "$dp.fin.Record")
.push("count").add("$sum", 1).get();
DBObject project= BasicDBObjectBuilder.start().push("$project")
.add("count", "$count").get();
DBObject group2 = BasicDBObjectBuilder.start().push("$group")
.add("_id", "Total Count")
.push("total").add("$sum", "$count").get();
// Suppose collection has been prepared
AggregationOutput aggr = collection.aggregate(Arrays.asList(unwind, match, group1, project, group2));
If you above query is correct. You could approach this below codes.
//Forming Unwind parts
DBObject unwind = new BasicObject("$unwind","$dp.fin.record");
//Forming Match parts
DBObject match = new BasicObject();
match.put("dp.mon","patch.metrics")
match.put("dp.fin.Record", new BasicDBObject("$exists",1));
//Forming Group parts
DBObject group1 = new BasicDBObject();
group1.put("_id", '$dp.fin.Record');
group1.put("count", new BasicDBObject("$sum", 1));
//Forming Project parts
DBObject project = new BasicDBObject();
project.put("count", '$count');
//Forming Group parts
DBObject group2 = new BasicDBObject();
group2.put("_id", 'Total Count');
group2.put("total", new BasicDBObject('$sum', '$count'));
/**
* Executing aggregation
*/
AggregationOutput output = mongoOperations.getCollection("employee").aggregate(unwind,
new BasicDBObject("$match",match),
new BasicDBObject("$group",group1),
new BasicDBObject("$project",project),
new BasicDBObject("$group",group2));
Hope this could help you.

how rebuild lucene indexes over hibernate search jpa with mongodb

I have accidentally deleted my index directory, now i am trying to rebuild all indexes.
I am using the hibernate search with JPA, lucene and MONGODB.
the following method is returning no results
public void rebuildIndex()throws Exception{
org.hibernate.search.jpa.FullTextEntityManager fem = org.hibernate.search.jpa.Search.getFullTextEntityManager(entityManager);
org.hibernate.search.query.dsl.QueryBuilder queryBuilder = fem.getSearchFactory().buildQueryBuilder().forEntity(Person.class).get();
org.apache.lucene.search.Query query = queryBuilder.all().createQuery();
FullTextQuery fullTextQuery = fem.createFullTextQuery(query, Person.class);
//fullTextQuery.initializeObjectsWith(ObjectLookupMethod.SKIP, DatabaseRetrievalMethod.FIND_BY_ID);
System.out.println(fullTextQuery.toString());
List<Person> results = fullTextQuery.getResultList();
fem.clear();
System.out.println(results.size());
for(Person p : results){
fem.index( p );
fem.flushToIndexes();
fem.clear();
}
//fem.createIndexer().startAndWait();
}
the method is returning no result. how should I get all data from mongoDb to rebuild index?
as hibernate search didn't work with criteria neither with JPQL and has his own JP-QL parser.
I couldn't create a findAll method to retrieve all objetcs
the only way was use a native mongoDb query:
org.hibernate.search.jpa.FullTextEntityManager fem = org.hibernate.search.jpa.Search.getFullTextEntityManager(entityManager);
Mongo mongo = new Mongo("127.0.0.1", 27017);
DB db = mongo.getDB("mainBase");
DBCollection dbCollection = db.getCollection("Persons");
DBCursor cursor = dbCollection.find();
Collection<String> ids = new ArrayList<String>();
String id = "";
while (cursor.hasNext()) {
id = cursor.next().get("_id").toString();
System.out.println(id);
ids.add(id);
}
System.out.println(">"+ids.size());
Person pes;
for(String p : ids){
pes = new Person();
pes.setId(p);
pes = find(pes);
System.out.println("indexing: "+pes.getId());
fem.index( pes );//index each element
fem.flushToIndexes();//apply changes to indexes
fem.clear();//free memory since the queue is processed
}

MongoDB Exception caching while updating data

Hello every one I'm new to mongodb. While i updating the table i have to get the return values in result. But it return undefined ,But in the case of find and insert the value in table it works properly.
bands.update({name:'Hollywood Rose'}, {$set:{year:2000}}, function(err, result) {
console.log("result----"+result) // it returns undefined
if (!err)
return context.sendJson(result, 404);
})
;
This code work in my case while i update value in the table in mongodb i did this code in playframe work for java . Hope it also help in you case.
MongoClient mongo=new MongoClient("localhost",27017);
/*mongo.setWriteConcern(WriteConcern.JOURNALED);*/
DB db = mongo.getDB("webportal");
DBCollection coll=db.getCollection("userdb");
//ObjectId id= new ObjectId(userid);
BasicDBObject doc2 = new BasicDBObject();
doc2.put("_id",userid);
BasicDBObject updateDocument = new BasicDBObject();
updateDocument .append("$set", new BasicDBObject("username", username1).append("password", password1).append("email", email1));
coll.update(doc2, updateDocument);