Segregate results from mongodb based on a particular field - mongodb

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.

Related

Salesforce Rest API - Upsert Array records

I want upsert an array Accounts with api standard. I have read that the composite can be used
PATCH /composite/sobjects/Account/MyExtId__c
{
"allOrNone" : false,
"records" : [{
"attributes" : {"type" : "Account"},
"Name" : "Company One",
"MyExtId__c" : "AAA"
}, {
"attributes" : {"type" : "Account"},
"Name" : "Company Two",
"MyExtId__c" : "BBB"
}]
}
Is it not possible to add a simple json like when integrating 1 single record?
For example:
PATCH /sobjects/Account/MyExtId__c
[
{
"Name" : "Company One",
"MyExtId__c" : "AAA"
},
{
"Name" : "Company Two",
"MyExtId__c" : "BBB"
}
]

How to select friends' data based on the same document?

How to select friends data from the user document.
EG:-
{
"_id" : ObjectId("5a70c1159d0e9b2c40bfbfed"),
"name" : "Mo Salah",
"profile_pic":"(LINK)",
"d":"d",
"id" : "1",
"friends" : [
{
"id" : "2",
"name" : "mike",
"image" : "(LINK)"
},
{
"id" : "3",
"name" : "Sam",
"image" : "(LINK)"
},
{
"id" : "4",
"name" : "John",
"image" : "(LINK)"
}
]
}
I want to search in the users' collection based on the IDs in friends' object/array.
EDIT
Output should be like
{
"_id" : ObjectId("5a70c1159d0e9b2c40bfbmde"),
"name": "mike",
"profile_pic":"(LINK)",
"id" : "2",
"friends":[{array of his friends too}]
}

How to filter array in Mongodb document using Spring

I have below document structure.
{
"_id" : { "teacherId" : "<teacherId>", "Year" : "<Year>" },
"groups" : [ {
"groupId" : "<uuid>",
"groupName" : "<name>",
"groupNameLowerCase" : "<name_in_lower_case>",
"description" : "<desc>",
"students" : ["<studentid1>", "<studentid2>", ...],
"editedDate" : "<currentTimestamp>"
},
...
],
"editedDate" : "<currentTimestamp>",
"points" : "<points>"
}
Consider that below two documents are present in DB
{
"_id" : { "teacherId" : "1", "Year" : "2016" },
"groups" : [ {
"groupId" : "123",
"groupName" : "Test1",
"groupNameLowerCase" : "test1",
"description" : "sample document",
"students" : ["11", "22"]
},
{
"groupId" : "234",
"groupName" : "Test2",
"groupNameLowerCase" : "test2",
"description" : "sample document",
"students" : ["11", "22"]
},
{
"groupId" : "345",
"groupName" : "Test3",
"groupNameLowerCase" : "test3",
"description" : "sample document",
"students" : ["21", "32"]
}
],
"points" : "650"
}
{
"_id" : { "teacherId" : "1", "Year" : "2015" },
"groups" : [ {
"groupId" : "123",
"groupName" : "HOCKEY",
"groupNameLowerCase" : "HOCKEY",
"description" : "HOCKEY team",
"students" : ["11", "22"]
},
{
"groupId" : "234",
"groupName" : "football",
"groupNameLowerCase" : "football",
"description" : "sample football",
"students" : ["11", "22"]
},
{
"groupId" : "345",
"groupName" : "Test3",
"groupNameLowerCase" : "test3",
"description" : "sample document",
"students" : ["21", "32"]
}
],
"points" : "650"
I want to select groups for the specified student and teacher combination. e.g. If I supply teacherid= 1 and student id =11 then query should return two documents with matching groups. I wrote below code to get the matching groups in document. But afterward I understand that elemMatch will only return first element matching. It will return two documents but with only one group in it.
Here I would like to understand the options available in Mongodb 2.4 to filter arrays in document returned by some query.
String teacherId = "1";
String studentId = "11";
Criteria documentSearchCriteria = where("_id.teacherId").is(teacherId)
.and("groups")
.elemMatch(where("students").in(studentId));
Criteria groupFilterCriteria = where("groups").elemMatch(where("students").in(studentBid));
BasicQuery query = new BasicQuery(documentSearchCriteria.getCriteriaObject(), groupFilterCriteria.getCriteriaObject());
List<GroupsDocument> groupsDocumentList = groupsMongoTemplate.find(query, GroupsDocument.class);
As you said elemMatch will retrieve only first object in an array so you have to use aggregate future to achieve your output
MatchOperation match = Aggregation.match(Criteria.where("_id.teacherId").is("1").and("groups.students").in(11));
UnwindOperation unwind = Aggregation.unwind("groups");
GroupOperation group = Aggregation.group("_id").push("groups").as("groups").first("points").as("points");
Aggregation aggregation = Aggregation.newAggregation(unwind, match, group);
AggregationResults<BasicDBObject> groupResults = mongoTemplate.aggregate(aggregation,
CustomGroupsDocument.class, BasicDBObject.class);
List<BasicDBObject> result = groupResults.getMappedResults();

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" }
]
})