MongoDB self join(aggregation) of collection with parent references - mongodb

Hello I have this collection, with parent references, I need to do self join on this collection, so that output will contain the children to maximum depth in one document and also get the output based on "Type" field.
{
"DescId" : "1",
"Desc" : "Testing",
"ParentId" : "null",
"Order" : 1.0,
"Type" : "A",
"Parent" : null
}
{
"DescId" : "1.1",
"Desc" : "Testing Child 1",
"ParentId" : "1",
"Order" : 1.0,
"Type" : "B",
"Parent" : "Testing"
}
{
"DescId" : "1.2",
"Desc" : "Testing Child 2",
"ParentId" : "1",
"Order" : 2.0,
"Type" : "B",
"Parent" : "Testing"
}
{
"DescId" : "1.1.1",
"Desc" : "Testing grand child 1",
"ParentId" : "1.1",
"Order" : 1.0,
"Type" : "C",
"Parent" : "Testing Child 1"
}
At present I have this output based on answer given to my previous question:
{
"ADescId" : "1",
"ADesc" : "Testing"
}
{
"BDescId" : "1.1",
"BDesc" : "Testing child 1"
}
{
"BDescId" : "1.2",
"BDesc" : "Testing Child 2"
}
{
"CDescId" : "1.1.1",
"CDesc" : "Testing grandchild 1"
}
I have tried doing $graphlookup aggregation on this collection, somehow data seems to get messed up. Please let me know if there is a way to achieve this. Thanks.
Desired output:
{
"ADescId" : "1",
"ADesc" : "Testing",
"BDescId" : "1.1",
"BDesc" : "Testing child 1",
"CDescId" : "1.1.1",
"CDesc" : "Testing grandchild 1"
}
{
"ADescId" : "1",
"ADesc" : "Testing",
"BDescId" : "1.2",
"BDesc" : "Testing Child 2"
}

Related

How set a field in an array as empty string if its null

If have a collection of levels. A sample document looks like below:
{
"_id" : ObjectId("5d89ccf8c3c948ac48e449fc"),
"id" : 1,
"name" : "option 1",
"optionLevel" : [
{
"id" : 1,
"deparmentId" : null,
"name" : "level 1"
},
{
"id" : 2,
"deparmentId" : null,
"name" : "level 2"
}
]
}
How can I project a documentId inside optionLevel as empty string if its null?
The following query can get us the expected output:
db.collection.aggregate([
{
$addFields:{
"optionLevel":{
$map:{
"input":"$optionLevel",
"as":"info",
"in":{
$mergeObjects:[
"$$info",
{
"deparmentId":{
$ifNull:["$$info.deparmentId",""]
}
}
]
}
}
}
}
}
]).pretty()
Data set:
{
"_id" : ObjectId("5d89ccf8c3c948ac48e449fc"),
"id" : 1,
"name" : "option 1",
"optionLevel" : [
{
"id" : 1,
"deparmentId" : null,
"name" : "level 1"
},
{
"id" : 2,
"deparmentId" : null,
"name" : "level 2"
}
]
}
Output:
{
"_id" : ObjectId("5d89ccf8c3c948ac48e449fc"),
"id" : 1,
"name" : "option 1",
"optionLevel" : [
{
"id" : 1,
"deparmentId" : "",
"name" : "level 1"
},
{
"id" : 2,
"deparmentId" : "",
"name" : "level 2"
}
]
}

I would like to add couple of fields from a collection(Release) into another collection(Story)based on matching conditions(ID) in Mongo DB

Collection: Story ( This is the main collection where 2 fields from the release collection needs to be appended.)
{
"_id" : ObjectId("5d131d93e2838c3b753e6631"),
"expand" : "schema,names",
"total" : 2,
"issues" : [
{
"expand" : "operations,versionedRepresentations,editmeta,changelog,renderedFields",
"id" : "131",
"fields" : {
"updateddate" : "2019-06-12T10:58:12.345+0530",
"fixVersions" : [
{
"id" : "10008",
"description" : "New Release 2",
"name" : "New Release 2"
},
{
"id" : "10009",
"description" : "New Release 3",
"name" : "New Release 3"
}
],
"aggregatetimespent" : null
}
},
{
"expand" : "operations,versionedRepresentations,editmeta,changelog,renderedFields",
"id" : "10032",
"fields" : {
"updateddate" : "2019-06-22T10:58:12.345+0530",
"fixVersions" : [
{
"id" : "10008",
"description" : "New Release 2",
"name" : "New Release 2"
}
],
"aggregatetimespent" : null
}
}
]
}
Collection: Release( This is another collection with few fields from which fields)
{
"_id" : ObjectId("5d131a35e2838c3b753e6626"),
"id" : "10008",
"startDate" : "2019-06-28",
"releaseDate" : "2019-07-05"
}
{
"_id" : ObjectId("5d131a35e2838c3b753e6626"),
"id" : "10009",
"startDate" : "2019-08-28",
"releaseDate" : "2019-09-05"
}
Start date and Release Date need to be appended to the array fields based on the condition.
Expected output:
Collection: Story
{
"_id" : ObjectId("5d131d93e2838c3b753e6631"),
"expand" : "schema,names",
"total" : 2,
"issues" : [
{
"expand" : "operations,versionedRepresentations,editmeta,changelog,renderedFields",
"id" : "131",
"fields" : {
"updateddate" : "2019-06-12T10:58:12.345+0530",
"fixVersions" : [
{
"id" : "10008",
"description" : "New Release 2",
"name" : "New Release 2",
"startDate" : "2019-06-28",
"releaseDate" : "2019-07-05"
},
{
"id" : "10009",
"description" : "New Release 3",
"name" : "New Release 3",
"startDate" : "2019-08-28",
"releaseDate" : "2019-09-05"
}
],
"aggregatetimespent" : null
}
},
{
"expand" : "operations,versionedRepresentations,editmeta,changelog,renderedFields",
"id" : "10032",
"fields" : {
"updateddate" : "2019-06-22T10:58:12.345+0530",
"fixVersions" : [
{
"id" : "10008",
"description" : "New Release 2",
"name" : "New Release 2",
"startDate" : "2019-06-28",
"releaseDate" : "2019-07-05"
}
],
"aggregatetimespent" : null
}
}
]
}

Segregate results from mongodb based on a particular field

My schema for list collection is-
list:
{
username : "some username",
listitem : "some item",
category : "some category",
status : "some status"
}
db.list.find() gets all the results, but I want to retrieve data based on category where the results with same category value appear together.Here is sample output of
db.list.find()
{
"_id" : ObjectId("585669eb4aa058f4e7972db3"),
"username" : "user1",
"listitem" : "item 1",
"status" : "P",
"category" : "A",
}
{
"_id" : ObjectId("5856a7c64aa058f4e7972db4"),
"username" : "user2",
"listitem" : "item 2",
"status" : "p",
"category" : "B",
}
{
"_id" : ObjectId("5858faedde3ffb11a083e770"),
"username" : "user1"
"listitem" : "item 3",
"status" : "p",
"category" : "A",
}
But I want all my 'A' category results together and 'B' category results together.
that is,output should be like this-
{
"_id" : ObjectId("5856a7c64aa058f4e7972db4"),
"username" : "user2",
"listitem" : "item 2",
"status" : "p",
"category" : "B",
}
{
"_id" : ObjectId("585669eb4aa058f4e7972db3"),
"username" : "user1",
"listitem" : "item 1",
"status" : "P",
"category" : "A",
}
{
"_id" : ObjectId("5858faedde3ffb11a083e770"),
"username" : "user1"
"listitem" : "item 3",
"status" : "p",
"category" : "A",
}
Please someone tell me how to do this.Whether this directly possible through mongodb query or I have to perform operations to format output in this form, when I get result in node js server?
It is a simple use case of sort
db.list.find().sort( { category: 1 } )
All the docs will be sorted by the corresponding category values and hence, all docs with the same category value will be listed together.

Spring rest docs nested object

We need to deliver a response for a call in the following form:
{
"3" : {
"id" : "3",
"parent" : "1",
"title" : "Folder 2",
"folder" : true
},
"4" : {
"id" : "4",
"parent" : "2",
"title" : "Folder 1.1",
"folder" : true
},
"doc:3" : {
"parent" : "3",
"title" : "Document 3",
"folder" : false
},
"doc:2" : {
"parent" : "2",
"title" : "Document 2",
"folder" : false
},
"doc:1" : {
"parent" : "3",
"title" : "Document 1",
"folder" : false
}
}
How should i document it? The Problem is that the object is a structure with EntryId as key and contains no id when its a document. Is there a option where I can use variables to define keys? Or whats recomended to use in responseFields ?
I had the same problem that Andy Wilkinson is pointing in the comments and instead of hardcode it in the ascii.doc, I did it like so:
,relaxedResponseFields(
fieldWithPath("key").description(getMessage(MessageProperties.TRANSLATION_RESOURCE_MAP_KEY)).type(MessageProperties.TYPE_STRING).optional(),
fieldWithPath("value").description(getMessage(MessageProperties.TRANSLATION_RESOURCE_MAP_KEY_VALUE)).type(MessageProperties.TYPE_MAP).optional(),
fieldWithPath("value[].key").description(getMessage(MessageProperties.TRANSLATION_RESOURCE_MAP_KEY_VALUE_KEY)).type(MessageProperties.TYPE_LONG).optional(),
fieldWithPath("value[].value").description(getMessage(MessageProperties.TRANSLATION_RESOURCE_MAP_KEY_VALUE_KEY_VALUE)).type(MessageProperties.TYPE_STRING).optional()
)
check How to document response fields for an object as Map(HashMap) for more info of the problem and if it really like yours.

MongoDB: How to update an entire document in a collection

In my application I need to edit a document... and while editing the document the current [unchanged] version should be still available to other users. For instance, when I start editing a document, I create a new copy of it in a separate collection, and when done I replace the current version with the new version of the temporary collection.
Let's assume the original document stored in collection users looks like this:
{
"_id" : ObjectId("53b986e2fe000000019a5a13"),
"name" : "Joe",
"birthDate" : "2080-12-11",
"publications" : [
{ "title" : "title 1", "description" : "description 1" },
{ "title" : "title 2", "description" : "description 2" }
]
}
Then, let's assume the document above is copied to another collection (e.g. users.wip) and modified like this:
{
"_id" : ObjectId("53b986e2fe000000019a5a13"),
"name" : "Joe",
"birthDate" : "1980-12-11",
"publications" : [
{ "title" : "bye bye", "description" : "Blah blah" },
{ "title" : "title 2", "description" : "description 2" },
{ "title" : "title 3", "description" : "description 3" }
]
}
How do I replace the whoe document? The problem is that when I try to update the original document with
{ "$set" : {
"name" : "Joe",
"birthDate" : "1980-12-11",
"publications" : [
{ "title" : "bye bye", "description" : "Blah blah" },
{ "title" : "title 2", "description" : "description 2" },
{ "title" : "title 3", "description" : "description 3" }
]
}}
I always get the following error message:
10150 Field name duplication not allowed with modifiers
That said, what's the correct way to update an entire document?
To replace the whole document, you don't use $set, but just provide the new doc to the update call:
db.test.update({"_id": ObjectId("53b986e2fe000000019a5a13")}, {
"_id" : ObjectId("53b986e2fe000000019a5a13"),
"name" : "Joe",
"birthDate" : "1980-12-11",
"publications" : [
{ "title" : "bye bye", "description" : "Blah blah" },
{ "title" : "title 2", "description" : "description 2" },
{ "title" : "title 3", "description" : "description 3" }
]
})
However, with the current 3.0 driver, it would be best to use replaceOne instead:
db.test.replaceOne({"_id": ObjectId("53b986e2fe000000019a5a13")}, {
"name" : "Joe",
"birthDate" : "1980-12-11",
"publications" : [
{ "title" : "bye bye", "description" : "Blah blah" },
{ "title" : "title 2", "description" : "description 2" },
{ "title" : "title 3", "description" : "description 3" }
]
})