We have the documents in the following structure. I am trying to write a service using "spring-data-mongo" to traverse the documents and print a report as shown below (in output).
db.getCollection("tree").find({})
// Result
{
"_id" : ObjectId("5467cswrtr")
"name" : "energy1",
"rootId" : "10",
"parent_id" : null,
"id" : "10"
},
{
"_id" : ObjectId("5467cswrt54r")
"name" : "energy2",
"rootId" : "10",
"parent_id" : 10,
"id" : "20"
},
{
"_id" : ObjectId("54cswrtr")
"name" : "energy3",
"rootId" : "10",
"parent_id" : "20",
"id" : "30"
},
{
"_id" : ObjectId("54cswrtr")
"name" : "energy4",
"rootId" : "10",
"parent_id" : "20",
"id" : "40"
}
We can visualize the above document in tree form as below. We may have many such trees.
Tree Structure:
We are using Mongo version 3.2.12. I need to print the following report by traversing the documents using spring data mongo:
Name rootId Depth
============================
energy1 10 3
Agriculture 99 36
-- and so on
PS: I searched on Google and found out about $graphlookup, but it does not seem to be supported in mongo version 3.2.12.
Please help.
Related
I have a collection with some documents like below:
{
"_id" : ObjectId("1"),
"className" : "model.MyClass",
"createdOn" : ISODate("2018-10-23T11:00:00.000+01:00"),
"status" : "A"
}
{
"_id" : ObjectId("2"),
"className" : "model.MyClass",
"createdOn" : ISODate("2018-10-23T11:01:00.000+01:00"),
"status" : "B"
}
{
"_id" : ObjectId("3"),
"className" : "model.MyClass",
"createdOn" : ISODate("2018-10-23T11:02:00.000+01:00"),
"status" : "C"
}
{
"_id" : ObjectId("4"),
"className" : "model.MyClass",
"createdOn" : ISODate("2018-10-23T11:03:00.000+01:00"),
"status" : "D"
}
Given a specific ID, how can I get the previous document that whose status not equals a specific status.
For example, I give the ID 4 and like to get the last document that status not is B neither C. So, I get the Object with Id 1.
How to create this query?
you could try this:
db.yourcollection.find( {"status":{"$nin":["B","C"]}}
).sort({_id:-1}).limit(1);
so use not in operator i.e. $nin, then sort the data in descending order and limit the records to 1
see below documentations for details.
$nin operator
mongo sort
Let's say I have the following entries in my MongoDB.
{ "_id" : ObjectId("5474af69d4b28042fb63b81b"), "name" : "a", "time" : NumberLong("1412774562000"), "location" : "DE" }
{ "_id" : ObjectId("5474af69d4b28042fb63b81c"), "name" : "b", "time" : NumberLong("1412774562020"), "location" : "DE" }
{ "_id" : ObjectId("5474af69d4b28042fb63b81d"), "name" : "c", "time" : NumberLong("1412774562040"), "location" : "US" }
{ "_id" : ObjectId("5474af69d4b28042fb63b81e"), "name" : "d", "time" : NumberLong("1412774562060"), "location" : "AU" }
{ "_id" : ObjectId("5474af69d4b28042fb63b81f"), "name" : "e", "time" : NumberLong("1412774562080"), "location" : "CN" }
As a result, I need to know how often each specific "location" can be found in the database e.g.
{"DE": "2",
"US": "1",
"AU": "1",
"CN": "1"}
I have no information about all the different locations in the database so querying after a known location for example
db.c.find({"location": "DE"})
would not solve my problem.
You need to make use of the aggregation pipeline with a group and project stage operators.
db.c.aggregate([
{$group:{"_id":"$location","count":{$sum:1}}},
{$project:{"location":"$_id","occurance":"$count"}}
])
I'm kind of stuck with the following problem. I have a MongoDB filled with documents, of these documents (I have a list with Id's) I need to insert a field.
I have this document:
{
"id" : 3639,
"type" : "P",
"createdate" : "2011-10-19T11:45:14+0200",
"name_creator" : "",
"latitude" : "50.887",
"longitude" : "9.14999",
"themes" : [{
"name" : "Fun",
"id" : "4"
}, {
"name" : "Kids",
"id" : "5"
}]
}
I need a query the can insert the themes field into the document, the current themes field does not have to be updates, just 1 new one. I have over 300 Id's where this has to be done.
The document should then look like this:
(all the other fields in themes should be removed, just one new one 'Outside')
{
"id" : 3639,
"type" : "P",
"createdate" : "2011-10-19T11:45:14+0200",
"name_creator" : "",
"latitude" : "50.887",
"longitude" : "9.14999",
"themes" : [{
"name" : "Outside",
"id" : "6"
}]
}
I would normally write a bit of Java code that would loop over the documents and change them, but I believe (hope) this could be done in a query.
Anyone got an idea on how I could do this?
Thanks for any help!
All you need to do is
db.collection.update(
{id : {$in : [your list of ids]}},
{$set : {
theme : [{
"name" : "Outside",
"id" : "6"
}]
}},
{multi : true}
)
I'm starting to work with MongoDB and I've a question about aggregation. I've a document that use a lot of different fields in different orders. For example:
db.my_collection.insert({ "answers" : [ { "id" : "0", "type" : "text", "value" : "A"}, { "id" : "1", "type" : "text", "value" : "B"}]})
db.my_collection.insert({ "answers" : [ { "id" : "0", "type" : "text", "value" : "C"}, { "id" : "1", "type" : "text", "value" : "A"}]})
I would to execute a query using "answers.id" with "answers.value" to obtain a result.
I tried but didn't get results, in my case, I executed the command:
db.my_collection.aggregate({$match: {"answers.id":"0", "answers.value": "A"}})
And the result was the two responses when I expected only:
{ "answers" : [ { "id" : "0", "type" : "text", "value" : "A"}, { "id" : "1", "type" : "text", "value" : "B"}]
Thank you!!!
You need to use the $elemMatch operator to match a single element of the answers array with both the specified 'id' and 'value'.
Something like this should work:
db.my_collection.aggregate( {
"$match" : {
"answers" {
"$elemMatch" : {
"id" : "0",
"value" : "A"
}
}
}
} )
MongoTemplate not returning results.
Json:
{
"_id" : ObjectId("51acf6ab0d5d46077ae12b2a"),
"docType" : "row",
"value" : {
"entity" : {
"#id" : "1111",
"#version" : "3434",
"name" : "XY XY",
"listId" : 28,
"listCode" : "BS",
"entityType" : "03",
"createdDate" : "09/12/2006",
"lastUpdateDate" : "04/20/2011",
"source" : "CCC",
"address1" : "XXXXXXXX",
"city" : "CITY",
"country" : "CO",
"countryName" : "COUNTRY NAME"
}
},
"createdDate" : ISODate("2013-06-03T20:03:55.127Z"),
"createdBy" : "Test"
}
Query:
queryy = new Query(Criteria.where("docType").is("row").andOperator(Criteria.where("value.entity.city").is("CITY")));
Above query doesn't return any result back.
Am I missing something? Please help.
Try this:
query = new Query(Criteria.where("docType").is("row")
.and("value.entity.city").is("CITY"));
You're code doesn't need the andOperator function (as that translates to $and). It just needs multiple criteria using and.
And, you can use query.toString() to see what the output would be of the query (and compare it to what you might have used in the MongoDB shell.