How to use aggregation on spring boot with mongodb - java

I am trying to get array list of specific field using aggregate function. I am trying to run below mongodb query:
db.txn.aggregate([
{ "$match" : { "name" : "piyush"}} ,
{ "$group" : { "_id" : null , "idList" : { "$push" : "$_id"}}} ,
{ "$project" : { "idList" : 1}}
])
It will return me below result:
{
"_id" : null,
"idList" : [
ObjectId("5c150672ec78951f4c1cff00"),
ObjectId("5c150673ec78951f4c1cff01"),
ObjectId("5c150673ec78951f4c1cff02")
]}
I want to implement same query using spring boot framework with mongodb so how can I achieve it?

You should try something like this :
Aggregation aggregation = Aggregation.newAggregation(
match(Criteria.where("name").is("Piyush")),
group("_id").push("_id").as("idList")
project("idList")
);
You can refer more details here :
https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/

Related

Trouble translating a MongoDB update query into spring boot

In my mongo database, I have the following document:
{
"_id" : ObjectId("5d1a08d2329a3c1374f176df"),
"associateID" : "1234567",
"associatePreferences" : [
{
"type" : "NOTIFICATION",
"serviceCode" : "service-code",
"eventCode" : "test-template",
"preferences" : [
"TEXT",
"EMAIL"
]
},
{
"type" : "URGENT_NOTIFICATION",
"serviceCode" : "service-code",
"eventCode" : "test-template",
"preferences" : [
"TEXT"
]
}
]
}
I am trying to add new elements to the preferences arrays based off of a given type, serviceCode, and eventCode. I was able to write this query in mongo as shown below:
db.user_communication_preferences.update(
{'associateID':'testassociate'},
{$addToSet:{'associatePreferences.$[element].preferences':"UPDATE"}},
{arrayFilters:[
{'element.serviceCode':'service-code',
'element.eventCode':'test-template',
'element.type':'NOTIFICATION'
}
]}
)
I am trying to translate this query into a java spring boot application. I saw some posts on here about doing this, but I didn't see any that incorporated arrayFilters. Can anyone lead me down the right path?

How perform query that delete elements from nested array in MongoDb using Morphia?

I have the following mongoDB object
{
"_id" : ObjectId("5c3f32a4e17c5739bccb9115"),
"name" : "John",
"friends" : [
{
"name" : "Paul"
},
{
"name" : "Lisa"
}
]
}
I need to delete some element from it. In native mongodb query it looks like
db.users.update({}, {$pull: {friends: {name:"Lisa"}}})
But how can I do this via Morhia API?
I resolve this issue by using:
Query<Group> query = getDatastore().createQuery(Group.class);
UpdateOperations<Group> ops = getDatastore().createUpdateOperations(Group.class)
.removeAll("friends", new BasicDBObject("name", "Lisa"));
getDatastore().update(query, ops);

Fetching mongo data in specific format

I have a mongo collection named 'demo', which is having the following structure:
{
"_id" : ObjectId("59d600182c44a11cec2b9ac5"),
"User_ID" : "user-12",
"Status" : {
"User_Status" : "Registered",
"Location" : "USA"
}
}
I have used the following mongo query to fetch data:
db.demo.find({},
{
User_ID:1,
"Status.User_Status":1
})
The output of above query is:
{
"_id" : ObjectId("59d600182c44a11cec2b9ac5"),
"User_ID" : "user-12",
"Status" : {
"User_Status" : "Registered"
}
}
But my requirement is to achieve the following output:
{
"_id" : ObjectId("59d600182c44a11cec2b9ac5"),
"User_ID" : "user-12",
"User_Status" : "Registered"
}
Is there any way to disable to parent document (Status) and get only result for sub-document "User_Status". Thanks for any help.
Yes, you can use aggregate with project instead of find
Use the below command get your desired result :
db.dummy.aggregate(
{
$project:
{
User_ID:1,
User_Status:"$Status.User_Status"
}
})
Use aggregate instead find and project operator.
db.demo.aggregate( {$project: {User_Status:'$Status.User_Status', User_ID:'$User_ID'}} );

How do I GroupBy in Spring Data Mongodb without Aggregation?

I have a data like below, and I want to group that data by the type, I'm using spring-data-mongodb .
[
{
"_id" : ObjectId("58a5518aace6132a88309d98"),
"type" : "SMS",
},
{
"_id" : ObjectId("58a5518bace6132a88309d99"),
"type" : "PUSH_NOTIFICATION",
},
{
"_id" : ObjectId("58a5519aace6132a0094d7df"),
"type" : "SMS",
},
{
"_id" : ObjectId("58a5519aace6132a0094d7e0"),
"type" : "PUSH_NOTIFICATION",
}
]
I'm using this method and won't work.
GroupByResults<Queuing> results = mongoTemplate.group("queuing",
GroupBy.key("type"), Queuing.class);
Anyone know the best and clear way to do this grouping using spring-data-mongodb.
Thanks.
This is the correct syntax for group operation.
GroupByResults<Queuing> results = mongoTemplate.group("queuing",
GroupBy.key("type").initialDocument("{}").reduceFunction("function(doc, prev) {}"),
Queuing.class);
More information here http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.group.example

How to write this Aggregate query in mongo template in spring

I want to write this aggregate query in mongo template using spring.
This is my query:
db.getCollection('CANdata_fc_distance_report').aggregate(
{$match: { device_datetime : { $gte :1462041000000, $lte: 1462732200000 }}},
{"$group" : {_id:{fc :"$fc",vehicle_name:"$vehicle_name",
device_id : "$device_id"},
count:{$sum:1}}}
)
This is the result of the above query
/* 1 */
{
"_id" : {
"fc" : NumberLong(1),
"vehicle_name" : "WPD 9020",
"device_id" : NumberLong(157)
},
"count" : 2
}
/* 2 */
{
"_id" : {
"fc" : NumberLong(2),
"vehicle_name" : "VVD 8966",
"device_id" : NumberLong(137)
},
"count" : 1
}
This is my data in table:
/* 1 */
{
"_id" : ObjectId("581829855d08921ee6f0ac39"),
"_class" : "com.analysis.model.mongo.fc_distance_report",
"device_id" : NumberLong(137),
"vehicle_name" : "VVD 8966",
"distance" : 125.01,
"fc" : NumberLong(1),
"device_datetime" : NumberLong(1462041000000)
}
/* 2 */
{
"_id" : ObjectId("581830335d08921ee6f0ad6b"),
"_class" : "com.analysis.model.mongo.fc_distance_report",
"device_id" : NumberLong(137),
"vehicle_name" : "VVD 8966",
"distance" : 171.88,
"fc" : NumberLong(2),
"device_datetime" : NumberLong(1462127400000)
}
I found example in my google search added match criteria but I have no idea how to write grouping on 3 columns
Aggregation agg = newAggregation(match(Criteria.where("device_datetime").exists(true)
.andOperator(
Criteria.where("device_datetime").gte(startDate),
Criteria.where("device_datetime").lte(endDate))),
group("hosting").count().as("total"),
project("total").and("hosting").previousOperation(),
sort(Sort.Direction.DESC, "total")
);
Please help me. Thank you
You can try something like this. Just and the group keys together.
Aggregation agg = newAggregation(match(Criteria.where("device_datetime").exists(true)
.andOperator(
Criteria.where("device_datetime").gte(startDate),
Criteria.where("device_datetime").lte(endDate))),
group(Fields.fields().and("fc", "$fc").and("vehicle_name", "$vehicle_name").and("device_id", "$device_id"))
.count().as("count"));

Categories

Resources