I have following aggregation query method:-
public List<String> fetchRelativeIds(String externalId) {
ProjectionOperation projectionOperation = project().and("ancestors._id")
.concatArrays("descendants._id").as("weNeedRelations").andInclude("_id");
MatchOperation filterByIds = Aggregation.match(new Criteria("externalIds.fenergo").is(externalId));
Aggregation aggregation = newAggregation(filterByIds, projectionOperation);
return mongoTemplate.aggregate(aggregation, Master.class.getSimpleName(), String.class).getMappedResults();
}
This gives me output as below:-
{ "_id" : { "$oid" : "5aafb705f3fabe7c915bca14"} , "weNeedRelations" : [ { "$oid" : "5aafb718f3fabe7c915bca1f"} , { "$oid" : "5aafb719f3fabe7c915bca23"} , { "$oid" : "5aafb6fbf3fabe7c915bca10"}]}
I just want the $oid value part as string nothing else. E.g.
{ "_id" : "5aafb705f3fabe7c915bca14" , "weNeedRelations" : [ "5aafb718f3fabe7c915bca1f" , "5aafb719f3fabe7c915bca23", "5aafb6fbf3fabe7c915bca10"]}
How could I do that?
Related
I have below Mongo DB aggregate query which is giving me the below output
Sample Documents in Mongodb
/* 4 */
{
"_id" : ObjectId("5a536d89e5b8f73d4e41ba96"),
"name" : "yyyyy",
"creationDate" : ISODate("2018-01-02T16:27:25.201Z"),
"address" : "xxx",
"zipcode" : "10254"
}
/* 5 */
{
"_id" : ObjectId("5a536d95e5b8f73d4e41ba97"),
"name" : "zzzzz",
"creationDate" : ISODate("2018-01-03T16:28:25.201Z"),
"address" : "xxx",
"zipcode" : "10254"
}
Aggregate Query
db.test_customer.aggregate([
{$match:{creationDate:{"$gte":ISODate("2018-01-01"),"$lt":ISODate("2018-01-05")}}},
{$project:{"_id":"$_id","name":"$name",creationDate:"$creationDate"}},
{$group:{"_id":"$_id",customer:{"$push":"$$ROOT"}}}
])
This gives me below result
/* 1 */
{
"_id" : ObjectId("5a536d95e5b8f73d4e41ba97"),
"customer" : [
{
"_id" : ObjectId("5a536d95e5b8f73d4e41ba97"),
"name" : "zzzzz",
"creationDate" : ISODate("2018-01-03T16:28:25.201Z")
}
]
}
/* 2 */
{
"_id" : ObjectId("5a536d89e5b8f73d4e41ba96"),
"customer" : [
{
"_id" : ObjectId("5a536d89e5b8f73d4e41ba96"),
"name" : "yyyyy",
"creationDate" : ISODate("2018-01-02T16:27:25.201Z")
}
]
}
When i try to convert to Java coding i am not getting the output. it is returning empty result
My Java code
DBCollection collection = mongoTemplate.getCollection("test_customer");
DBObject match = new BasicDBObject("$match", new BasicDBObject("creationDate", new BasicDBObject("$gte", getDate("01/01/2018")).append("$lt", getDate("05/01/2018"))));
DBObject project = new BasicDBObject("$project", new BasicDBObject("_id", "$_id").append("name", "$name").append("creationDate", "$creationDate"));
DBObject group = new BasicDBObject("$group", new BasicDBObject("_id", "$_id").append("customer", new BasicDBObject("$push", "$$ROOT")));
AggregationOutput aggregate = collection.aggregate(Arrays.asList(match, project, group));
Iterable<DBObject> results = aggregate.results();
for (DBObject obj : results) {
String obj1 = (String) obj.toString();
System.out.println(obj1);
}
private Date getDate(String date) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date1 = sdf.parse(date);
return date1;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
My Java code is creating aggregate query like below
db.test_customer.aggregate([
{ "$match" : { "creationDate" : { "$gte" : { "$date" : "2017-12-31T18:30:00.000Z"} , "$lt" : { "$date" : "2018-01-04T18:30:00.000Z"}}}},
{ "$project" : { "_id" : "$_id" , "name" : "$name" , "creationDate" : "$creationDate"}},
{ "$group" : { "_id" : "$_id" , "customer" : { "$push" : "$$ROOT"}}}
])
I don't know why $date is not picking the ISODate in mongodb. Please suggest me how to use aggregate date condition in mongodb
I am new to MongoDB, and I have to create simple site using jsp/servlet.
I need to a create query that will return count of how many times some site has been visited.
My DB looks like this:
{ "_id" : { "$oid" : "5117fa92f1d3a4093d0d3902"} , "ip" : "127.0.0.1" , "datum" : { "$date" : "2013-02-10T19:52:50.051Z"} , "odlaznaStr" : "localhost:8080/mongoProjekat/" , "dolaznaStr" : "localhost:8080/mongoProjekat/treca"}<br>
{ "_id" : { "$oid" : "5117fa92f1d3a4093d0d3903"} , "ip" : "127.0.0.1" , "datum" : { "$date" : "2013-02-10T19:52:50.796Z"} , "odlaznaStr" : "localhost:8080/mongoProjekat/treca.jsp" , "dolaznaStr" : "localhost:8080/mongoProjekat/peta"}<br>
{ "_id" : { "$oid" : "5117fa93f1d3a4093d0d3904"} , "ip" : "127.0.0.1" , "datum" : { "$date" : "2013-02-10T19:52:51.141Z"} , "odlaznaStr" : "localhost:8080/mongoProjekat/peta.jsp" , "dolaznaStr" : "localhost:8080/mongoProjekat/treca"}<br>
{ "_id" : { "$oid" : "5117fa93f1d3a4093d0d3905"} , "ip" : "127.0.0.1" , "datum" : { "$date" : "2013-02-10T19:52:51.908Z"} , "odlaznaStr" : "localhost:8080/mongoProjekat/treca.jsp" , "dolaznaStr" : "localhost:8080/mongoProjekat/cetvrta"}<br>
{ "_id" : { "$oid" : "5117fa94f1d3a4093d0d3906"} , "ip" : "127.0.0.1" , "datum" : { "$date" : "2013-02-10T19:52:52.035Z"} , "odlaznaStr" : "localhost:8080/mongoProjekat/treca.jsp" , "dolaznaStr" : "localhost:8080/mongoProjekat/cetvrta"}<br>
{ "_id" : { "$oid" : "5117fa94f1d3a4093d0d3907"} , "ip" : "127.0.0.1" , "datum" : { "$date" : "2013-02-10T19:52:52.197Z"} , "odlaznaStr" : "localhost:8080/mongoProjekat/cetvrta.jsp" , "dolaznaStr" : "localhost:8080/mongoProjekat/treca"}
What I need is a result that will look something like this:
page: localhost:8080/mongoProjekat/treca visited: n(times)<br>
page: localhost:8080/mongoProjekat/druga visited: n(times)
...and so on for every page that has been visited.
I am using Java, by the way.
You may find this SQL to MongoDB chart http://docs.mongodb.org/manual/reference/sql-aggregation-comparison/ helpful.
As for your immediate question:
// getCollection
DBCollection myColl = db.getCollection("toskebre");
// for the $group operator
// note - the collection still has the field name "dolaznaStr"
// but, to we access "dolaznaStr" in the aggregation command,
// we add a $ sign in the BasicDBObject
DBObject groupFields = new BasicDBObject( "_id", "$dolaznaStr");
// we use the $sum operator to increment the "count"
// for each unique dolaznaStr
groupFields.put("count", new BasicDBObject( "$sum", 1));
DBObject group = new BasicDBObject("$group", groupFields );
// You can add a sort to order by count descending
DBObject sortFields = new BasicDBObject("count", -1);
DBObject sort = new BasicDBObject("$sort", sortFields );
AggregationOutput output = myColl.aggregate(group, sort);
System.out.println( output.getCommandResult() );
The println will print:
{ "serverUsed" : "localhost/127.0.0.1:27017" ,
"result" : [ { "_id" : "localhost:8080/mongoProjekat/treca" , "count" : 3} ,
{ "_id" : "localhost:8080/mongoProjekat/cetvrta" , "count" : 2} ,
{ "_id" : "localhost:8080/mongoProjekat/peta" , "count" : 1}] ,
"ok" : 1.0}
Ty for answer Kay. I allready found solution that is similar to yours.
I have done it this way:
DBObject match = new BasicDBObject("stranica","$dolaznaStr");
DBObject project = new BasicDBObject("$project",match);
DBObject id = new BasicDBObject("_id",new BasicDBObject("stranica","$stranica"));
id.put("posete", new BasicDBObject("$sum", 1));
DBObject group = new BasicDBObject("$group",id);
DBObject srt = new BasicDBObject("posete",-1);
DBObject sort = new BasicDBObject("$sort", srt);
AggregationOutput ao = collection.aggregate(project, group, sort);
I am new to java. How can I build this mongo query in java. Any help/hint will be appreciated.
db.places.find({loc : { $near :[ -122.934326171875,37.795268017578] , $maxDistance : 50 } ,$or:[{"uid":"at"},{"myList.$id" :ObjectId("4fdeaeeede2d298262bb80") } ] ,"searchTag" : { $regex : "Union", $options: "i"} } );
By using the QueryBuilder you can create the query you wanted. I have created it as follows.
QueryBuilder query = new QueryBuilder();
query.put("loc").near(-122.934326171875, 37.795268017578, 50);
query.or(
QueryBuilder.start("uid").is("at").get(),
QueryBuilder.start("myList.$id").is(new ObjectId("5024f2f577a59dd9736ddc38")).get()
);
query.put("searchTag").regex(Pattern.compile("Union",Pattern.CASE_INSENSITIVE));
When I print the query into the console it looks like :
{ "loc" : { "$near" : [ -122.934326171875 , 37.795268017578 , 50.0]} ,
"$or" : [ { "uid" : "at"} , { "myList.$id" : { "$oid" : "5024f2f577a59dd9736ddc38"}}] ,
"searchTag" : { "$regex" : "Union" , "$options" : "i"}
}
I didn't try it but hope it will work.
What is the equivalent cde in Java:
var result = collectionName.findOne()
println(result.get("name").toString)
To elaborate, This is my sample db:
{ "_id" : ObjectId("4ca039f7a5b75ab98a44b149"), "name" : "kaustubh", "country" : "india" }
{ "_id" : ObjectId("4ca03a85a12344a5e47bcc5c"), "name" : "rahul", "country" : "pakistan" }
{ "_id" : ObjectId("4ca03a9ea12344a5e47bcc5d"), "name" : "swapnil", "country" : "lanka" }
{ "_id" : ObjectId("4ca03b19a12344a5e47bcc5e"), "name" : "sagar", "country" : "nepal" }
i am running the following query on it:
query.put("country", "india");
DBCursor cursor = collection.find(query);
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
that prints:
{ "_id" : { "$oid" : "4ca04b6b37a85ab92557218a"} , "name" : "kaustubh" , "country" : "india"}
as many times as the pair exists in the collection.
how do I formulate a query to get all the names, once and get the count for them.I read the docs, and didnt stumble upon any way to do it.
Try this
query.put("name", "kaustubh");
DBObject myDoc = collection.findOne(query);
System.out.println(myDoc);
This is my current query: Using Java+mongoDB
{
BasicDBObject select = new BasicDBObject();
select.put("info.name.fn", 1);
DBCursor cursor = collection.find(new BasicDBObject(), select);
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
It gives an output as:
{ "_id" : { "$oid" : "123"} , "info" : { "name" : { "fn" : "foo"}}}
{ "_id" : { "$oid" : "123"} , "info" : { "name" : { "fn" : "bar"}}}
{ "_id" : { "$oid" : "123"} , "info" : { "name" : { "fn" : "baz"}}}
_ids changed to accommodate the output. My question is, what query do I give to get the output as:
foo
bar
baz
Is it even possible? Or does every query always return it in the above format? I cant run a distinct() because there are duplicate names.
Thanks.
The minimal query result you can get is the one you show above.
You do not have to print all of that, though.
System.out.println(cursor.next().get("info").get("name").get("fn"));