I have a mongoshell query like the below
db.viewedProfile.aggregate(
{$match : { "viewedMemberId": "54d6dd15e4b0611ba5762e3d" }},
{$group : { _id: null,
total: {$sum: "$count"}}})
I am struggling with converting this to spring data mongodb. I am using spring data version 1.4.3.RELEASE. the aggregation constructor seems to not recognize the match method.
This should do it:
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
...
Aggregation aggregation = newAggregation(
ViewedProfile.class,
match(Criteria.where("viewedMemberId").is("54d6dd15e4b0611ba5762e3d")),
group().sum("count").as("total")
);
Related
I am new to stackoverflow and also to Apache Camel. I try to write a understandable description of my problems.
My goal is to read hierarchical data from database (mysql) which is composed by 1 entry in a parent table and several rows in a child table and transform this data into a pojo.
Sub-goal: Not to write much custom code and use blueprint xml.
Since I could not find fitting EIP for this issue, I list here my approaches so far:
1. Select data by a joined query
select * from parentTable join childTable on childTable.parentId=parentTable.id
This would mean to write a custom processor to transform result into pojo, because the select result will get for each result row every time the parent properties. Since I try to avoid writing a custom processor, I tried the following:
2. Select query returns JSON with correct structure to transform to pojo
select json_object(
'parentProperty1', parentProperty1
, 'parentProperty2', parentProperty2
, 'children', (select CAST(CONCAT('[',
GROUP_CONCAT(
JSON_OBJECT(
'childProperty1', childProperty1
, 'childProperty2', childProperty2
)),
']')
AS JSON)
from childTable c
where p.messageId=c.messageId
)
))
from parentTable p
;
Executing the query on mysql shell returns expected JSON:
{
"parentProperty1": "value1",
"parentProperty1": "value2",
"children": [
{
"childProperty1": "value3",
"childProperty2": "value4"
},
{
"childProperty1": "value5",
"childProperty2": "value6"
}
]
}
Running the query inside camel, I encountered a problem, for which I could not find an explanation nor solution yet.
The body has after the execution of the query the JSON, but it is surrounded by fragments of the initial query:
[{json_object('parentProperty1', parentProperty1 , 'parentProperty2', parentProperty2 , 'children', (select CAST(CONCAT('[',
={"parentProperty1": "value1", "parentProperty2": "value2", "children": [{"childProperty1": "value3", "childProperty2": "value4"}, {"childProperty1": "value5", "childProperty2": "value6"}]}}]
Questions:
Is there an existing EIP to solve my problem?
Why there is no correct JSON as result in my 2. approach?
Thanks in advance
What you are actually getting is a key-value pair. Since no alias name was given to json_obect in the query, mysql generates a default column name. This is what you are seeing as query snippet in the result.
Add an alias name to the json_obect in the query as shown below:
select json_object(
'parentProperty1', parentProperty1
, 'parentProperty2', parentProperty2
, 'children', (select CAST(CONCAT('[',
GROUP_CONCAT(
JSON_OBJECT(
'childProperty1', childProperty1
, 'childProperty2', childProperty2
)),
']')
AS JSON)
from childTable c
where p.messageId=c.messageId
)
) as result
from parentTable p;
This would return something like this:
{result={"children": [{"childProperty1": "value3", "childProperty2": "value4"}, {"childProperty1": "value5", "childProperty2": "value6"}], "parentProperty1": "value1", "parentProperty2": "value2"}}
Hope this solves you issue
I need to implement aggregation in Spring-Data MongoDB.
This aggregation $group works successfully in Mongo Compass:
$group{
{
_id: { $dateToString: { format: "%Y-%m-%d", date: "$date" }},
doc: {"$push":"$$ROOT"}
}
}
This is the result expected group by year month and day and push results with all field in array docs
I try to implement this aggregation Spring Mongo:
My problem is that lose data and only get a date by the previous projection.
I prefer not use the $project and only $group stage.
I want to do a full text search on string "user" which can match any feild in my document and then apply filter so that i get only records where the value of x feild is either "abc" or "xyz".
Fiddling with Sense , the below request fulfills my requirement.
GET _search
{
"query":{
"filtered":{
"query":{
"query_string": {
"query": "user"
}
},
"filter":
[
{"term": { "x": "abc"}},
{"term": { "x": "xyz"}}
]
}
}
}
But, i want a java api to do the above stuff. I have searched the elastic documentation and the SO , but have not found what i am looking for as api like QueryBuilders.filteredQuery seems deprecated . I am currently using 2.3.4 but can upgrade.
Elasticsearch 2.x java Api doesn't have implementation for filtered query. According to the elasticsearch documentation, they suggest to use the bool query instead with a must clause for the query and a filter clause for the filter.
In java you could create a method to create a wrapper method for the filtered query. This would be like:
public static QueryBuilder filteredQuery(QueryBuilder query, QueryBuilder filter){
BoolQueryBuilder filteredQuery = QueryBuilders.boolQuery().must(query);
return filteredQuery.filter(filter);
}
where,
QueryBuilder query = QueryBuilders.queryStringQuery("user");
QueryBuilder filter = QueryBuilders.boolQuery().filter(QueryBuilders.boolQuery().should(QueryBuilders.termsQuery("x", "abc", "xyz")));
This query is equivalent to the one mentioned above. Hope this helps
I am using MongoDB 3.2 with Java. I read the documentation and it says to use org.bson.BsonDocument since other options like BSONObject and Document are deprecated. Now, I have query similar to:
db.schools.find({ zipcode: "63109" },
{ students: { $elemMatch: { school: 102 } } } )
I am wondering: how can I write this query in Java?
Note: Here we have two documents inside the find function, while it accepts only single Bson Document or multiple Bson Element(s).
Any help would be appreciated.
Try to use one document for the condition, like db.schools.find({ zipcode: "000000", students: { $elemMatch: { school: 102 }});
EDIT:
So, you are using Projection. In java mongodb driver 3.3 there are: public DBCursor find(DBObject query, DBObject projection). I think you should update your java mongodb driver.
How to get all the document under array in mongodb java. My Database is as below. Want to retrieve all the data under array 198_168_1_134.
below is some of What i tried,
eventlist.find(new BasicDBObject("$match","192_168_10_17"))
eventlist.find(new BasicDBObject("$elemMatch","192_168_10_17"))
eventlist.find(null, new BasicDBObject("$192_168_10_17", 1))
You have two options:
using .find() with cherry-picking which document you have to have fetched.
using the aggregation framework by projecting the documents.
By using .find() , you can do:
db.collection.find({}, { 192_168_10_17 : 1 })
By using the aggregation framework, you can do:
db.collection.aggregate( { $project : { 192_168_10_17 : 1 } } )
which will fetch only the 192_168_10_17 document data.
Of course, in order to get this working in Java, you have to translate these queries to a corresponding chain of BasicDBObject instances.
By using mongo java driver you can do this by following query -
eventlist.find(new BasicDBObject(), new BasicDBObject("198_168_1_134", 1))