I have a mongodb query which works fine
db.user.aggregate([
{
"$project": {
"data": {
"$objectToArray": "$$ROOT"
}
}
},
{
$unwind: "$data"
},
{
"$match": {
"data.v": {
$regex: "Mohit Chandani"
}
}
}
])
It basically, get all the document having the value Mohit Chandani and here is the output:
{ "_id" : "b387d728-1feb-45b6-bdec-dafdf22685e2", "data" : { "k" : "fullName", "v" : "Mohit Chandani" } }
{ "_id" : "8e35c497-4296-4ad9-8af6-9187dc0344f7", "data" : { "k" : "fullName", "v" : "Mohit Chandani" } }
{ "_id" : "c38b6767-6665-46b8-bd29-645c41d03850", "data" : { "k" : "fullName", "v" : "Mohit Chandani" } }
I need this query to be converted for my spring boot application and I am writing the following:-
Aggregation aggregation = Aggregation.newAggregation(Aggregation.project(Aggregation.ROOT), Aggregation.match(Criteria.where(connectionRequest.getWord())));
It would be helpful to know which approach to take when you do long aggregations in Spring-Data.
This might help you, Hope you are using MongoTemplate for aggregation.
#Autowired
private MongoTemplate mongoTemplate;
And the code for above script is
public List<Object> test() {
Aggregation.newAggregation(
project().and(ObjectOperators.valueOf(ROOT).toArray()).as("data"),
unwind("data"),
match(Criteria.where("data.v").regex("Mohit Chandani")
)
).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());
return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(YOUR_COLLECTION.class), Object.class).getMappedResults();
}
I'm not sure the project() of above code would work, because I haven't tried it. I referred it form Spring data mongodb
If it doesn't work, this would definitely work. Few opetaiotion are not suppored in spring data like $addFields, $filter.. So we do a Trick to convert
public List<Object> test() {
Aggregation aggregation = Aggregation.newAggregation(
p-> new Document("$project",
new Document("data",
new Document("$objectToArray","$$ROOT")
)
),
unwind("data"),
match(Criteria.where("data.v").regex("Mohit Chandani"))
).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());
return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(YOUR_COLLECTION.class), Object.class).getMappedResults();
}
Related
I wrote mongodb query. And am facing some issue while converting it in spring boot using aggregation class.So, please help me, i want it to convert it in spring boot using aggregation class.
db.api_audit.aggregate([{
$match: {
merchant_id: '015994832961',
request_time: {$gte: ISODate("2017-05-11T00:00:00.0Z"),
$lt: ISODate("2017-05-12T00:00:00.0Z")}}},
{
$group:
{
_id: {
SERVICE_NAME: "$service_name",
STATUS: "$status"
},
count: {
"$sum": 1
}
}
}, {
$group: {
_id: "$_id.SERVICE_NAME",
STATUSCOUNT: {
$push: {
Service_name: "$_id.STATUS",
count: "$count"
}
}
}
},
{ $sort : { "STATUSCOUNT.count" : -1} }
])
Below is the db query response
{
"_id" : "sendOTP",
"STATUSCOUNT" : [
{
"status" : "SUCCESS",
"count" : 2.0
}
]
}
Thanks in advance.
First you create all the required operations and then you add them to an aggregation pipeline. Then you feed it to an autowired mongotemplate.
Something like this:
#Autowired
private final MongoTemplate mongoTemplate;
void aggregate()
{
Criteria match = where("merchant_id").is("015994832961").andOperator(where("request_time").gte(Date.parse("2017-05-11T00:00:00.0Z")).lt(Date.parse("2017-05-11T00:00:00.0Z")));
GroupOperation groupOperation1 = group(fields().and("SERVICE_NAME").and("STATUS")).count().as("count");
GroupOperation groupOperation2 = ...//(not sure how push works here, but it should not be hard to figure out)
SortOperation sortOperation = sort(DESC, "STATUSCOUNT.count");
Aggregation aggegation = Aggregation.newAggregation(match, groupOperation1, groupOperation2, sortOperation);
List<Result> results = mongoTemplate.aggegate(aggregation, ObjectOfCollectionToRunOn.class, Result.class).getMappedResults();
}
I want to implement a search as you type functionality in Elastic Search using Java API. The queries that I want to transform to Java are below.
Do you have any idea, how can I execute this queries in Java?
These queries are very similar but I want to solve at least one.
This is my initial approach:
SearchResponse response = client.prepareSearch("kal")
.setTypes("products")
.setQuery(multiMatchQuery("description_en", "name", "description_en"))// Query
.setFrom(0).setSize(60).setExplain(true)
.get();
SearchHit[] results = response.getHits().getHits();
for (SearchHit hit : results) {
String sourceAsString = hit.getSourceAsString();
Map<String, SearchHitField> responseFields = hit.getFields();
SearchHitField field = responseFields.get("product_id");
Map map = hit.getSource();
System.out.println(map.toString());
}
Queries:
POST /kal/products/_search?pretty
{
"suggest": {
"name-suggest" : {
"prefix" : "wine",
"completion" : {
"field" : "suggest_name"
}
}
}
}
GET /kal/products/_search
{ "query": {
"prefix" : {
"name" : "wine",
"description": "wine"
}
}
}
GET /kal/products/_search
{
"query" : {
"multi_match" : {
"fields" : ["name", "description_en"],
"query" : "description_",
"type" : "phrase_prefix"
}
}
}
I am using an aggregate query in mongodb to find the sum of an attribute in all the documents present in a collection.
Query:
db.conversation.aggregate( [
{
$match:{
$and:[{"mailBoxId":"1","isHidden":false}]
}
},
{
$group:
{
_id: {"mailBoxId":"$mailBoxId","isHidden":"$isHidden"} ,
messageCount: { $sum:"$messageCount" }
}
}
]);
The result returned by Mongodb is fine and is in this format.
{
"result" : [
{
"_id" : {
"mailBoxId" : "2",
"isHidden" : false
},
"messageCount" : 2
}
],
"ok" : 1
}
I just want the messageCount field. I am using MongoTemplate(Spring) class to query the database.
Query retrievalQuery = new Query();
retrievalQuery.addCriteria(Criteria.where("mailBoxId").is(userId).and("isHidden").is(false));
return mongoTemplate.find(retrievalQuery, );
I am confused how to store the resultant object returned by Mongodb and extract a specific field from it.
Pls help.
The way you are trying to use aggregate in mongoTemplate is wrong . Try this i am sure it will help.
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(
Criteria.where("mailBoxId").is("1").and("isHidden").is(false)),
Aggregation.group("$mailBoxId").sum("$unReadMessagesCount").as("unReadMessagesCount")
);
System.out.println("Query ==>>["+agg.toString()+"]");
AggregationResults<AggResultObj> data = mongoTemplate.aggregate(agg, "collectionName", AggResultObj.class);
System.out.println("UnReadMesasgeCode :"+data.getUniqueMappedResult().getUnReadMessagesCount());
The AggResultObj will be looks like
public class AggResultObj{
String _id;
int unReadMessagesCount;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public int getUnReadMessagesCount() {
return unReadMessagesCount;
}
public void setUnReadMessagesCount(int unReadMessagesCount) {
this.unReadMessagesCount = unReadMessagesCount;
}
}
For more information you can see my blog where i have created a example for the same for your scenario. please click https://satishkumardangi.blogspot.in/2016/09/using-mongo-db-aggregation-with-spring.html
Try this
Query retrievalQuery = new Query();
retrievalQuery.addCriteria(Criteria.where("mailBoxId").is(userId).and("isHidden").is(false));
var result = mongoTemplate.find(retrievalQuery);
var final = result[1].messageCount;
return final;
I'm asking mongodb from my Spring data application using aggregation and when I get the result I need to cast it (or transform it) to my own object or type and I don't know how.
This is my code
AggregationResults aggregationResults = DBManager.getInstance().getMongoOperation().aggregate(aggregation, LevelEntity.class,Object.class);
I would like to have something like
AggregationResults<LevelList> aggregationResults = DBManager.getInstance().getMongoOperation().aggregate(aggregation, LevelEntity.class,LevelList.class);
and it gives me back this information
{
"_id" : {
"date" : "24/03/2015"
},
"levels" : [
{
"_id" : ObjectId("54f8627071fdac0ec132b4e5"),
"_class" : "org.xxxxxxxxxxx.persistence.model.impl.LevelEntity",
"user" : {
"_id" : ObjectId("54da19ce71fd56a173a3451a"),
...
...
...
},
"level" : 4,
"date" : ISODate("2015-03-24T14:04:32.830Z"),
"dateFormatted" : "24/03/2015"
},
{
"_id" : ObjectId("54f8627071fdac0ec132b4f4"),
"_class" : "org.xxxxxxxxxxx.persistence.model.impl.LevelEntity",
"user" : {
"_id" : ObjectId("54e34bd671fde9071569650c"),
...
...
...
},
"level" : 3,
"date" : ISODate("2015-03-24T14:04:32.866Z"),
"dateFormatted" : "24/03/2015"
}
]
}
Can you please help me!!???
Thanks a lot
Use as follow
TypedAggregation<LevelList> aggregation=Aggregation.newAggregation(LevelList.class,
match, sortOp, skipOp, limitOp);
AggregationResults<LevelList> data = mongoTemplate.aggregate(aggregation,
COLLECTION_NAME, LevelList.class);
well Cataclysm your response is not totally correct but gave me the key to solve my problem, this is what I had to do
TypedAggregation<LevelEntity> aggregation = Aggregation.newAggregation(LevelEntity.class,
userMatchOperation, dateMatchOperation, group(LevelEntity.DATE_FORMATTED_FIELD).push(ROOT).as(LevelByDate.ENTITY_NAME));
AggregationResults<LevelByDate> data = DBManager.getInstance().getMongoOperation().aggregate(aggregation, HappinessByDate.class);
And this is the LevelByDate object
#Document
public class LevelByDate {
public static final String ENTITY_NAME = "levelEntity";
#Id
private String id;
List<LevelEntity> levelEntity;
public LevelByDate() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<LevelEntity> getLevelEntity() {
return levelEntity;
}
public void setLevelEntity(List<LevelEntity> levelEntity) {
this.levelEntity = levelEntity;
}
}
Thanks a lot,
Kike.
I am new bie to spring framework. I have my mongo document like
{
"_id" : ObjectId("527242d584ae917d8bd75c7b"),
"postTitle" : "Car",
"postDesc" : "rent",
"owner" : ObjectId("526a588f84aed6f41cca10bd"),
"intrest" : []
}
What I want is to search document having id
"_id" : ObjectId("527242d584ae917d8bd75c7b")
and update it to
{
"_id" : ObjectId("527242d584ae917d8bd75c7b"),
"postTitle" : "Car",
"postDesc" : "rent",
"owner" : ObjectId("526a588f84aed6f41cca10bd"),
"intrest" : [
{
"userId" : ObjectId("526a587d84aed6f41cca10bc"),
"timestamp" : ISODate("2013-10-31T11:45:25.256Z")
},
{
"userId" : ObjectId("526a587d84aed6f41cca10bc"),
"timestamp" : ISODate("2013-11-31T11:55:25.256a")
}
]
}
my domain is
#Document
public class Post {
#Id
private ObjectId _id;
private String postTitle;
private String postDesc;
private ObjectId owner=Global.getCurruser();
private List<Intrest> intrest = new ArrayList<Intrest>();
// Getters and setters
}
#Document
public class Intrest {
private ObjectId userId;
private Date timestamp;
// Getters and setters
}
What upsert should I write to add or modify entries in intrest array[].
Please Help.
I am using spring-mongodb .. Here is what I do
Intrest insertObj = new Insert();
//initilize insert obj here ..
Update args = new Update();
args.addToSet("intrest",insertObj);
Query query = new Query(Criteria.where("id").is("527242d584ae917d8bd75c7b"));
// if u want to do upsert
mongoOperation.findAndModify(query, args, FindAndModifyOptions.options().upsert(true), Post.class);
//if u want to just update
mongoOperation.findAndModify(query, args, Post.class);
I think what you intend to do is an update. Upsert will modify your document matching the given query if not it will create a new document , where as update will only modify your document if found. here is the reference
I do not know about java, but all you need to do is $pushAll operator (I really hope you can find how to do this with java driver).
db.collection.update(
{"_id" : ObjectId("527242d584ae917d8bd75c7b")},
{ $pushAll: { intrest: [ {
"userId" : ObjectId("526a587d84aed6f41cca10bc"),
"timestamp" : ISODate("2013-10-31T11:45:25.256Z")
},
{
"userId" : ObjectId("526a587d84aed6f41cca10bc"),
"timestamp" : ISODate("2013-11-31T11:55:25.256a")
}] } }
);