Salesforce Rest API - Upsert Array records - rest

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

Related

How to create MongoDB Update query to update certain elements in an array of objects

I have a mongodb collection with thousands of documents. I have different steps in this collection and their steps status is completed. I want to update particular steps status from Completed to Open. For example, I want to update status to "Open"only for steps three and four and the document overAllStatus to Started. I want to do this where "executionId" is "20200622104036256".
My documents/json structure. Collection name order_status
{
"_id" : ObjectId("5ef03d8f5f5775000921e5b9"),
"executionId" : "20200622104036256",
"stateNumber" : "123456",
"overAllStatus" : "Completed",
"steps" : [{
"name" : "Step One",
"status" : "Completed"
}, {
"name" : "Step Two",
"status" : "Completed"
}, {
"name" : "Step Three",
"status" : "Completed"
}, {
"name" : "Step Four",
"status" : "Completed"
}],
"ABC" : {
"status" : "Completed"
}
}
After i execute the shell update script/query. All the documents where the "executionId" is "20200622104036256" will be looking as below
{
"_id" : ObjectId("5ef03d8f5f5775000921e5b9"),
"executionId" : "20200622104036256",
"stateNumber" : "123456",
"overAllStatus" : "Started",
"steps" : [{
"name" : "Step One",
"status" : "Completed"
}, {
"name" : "Step Two",
"status" : "Completed"
}, {
"name" : "Step Three",
"status" : "Open"
}, {
"name" : "Step Four",
"status" : "Open"
}],
"ABC" : {
"status" : "Completed"
}
}
Query :
/** Using updateMany to update multiple documents matching certain criteria */
db.order_status.updateMany(
{ executionId: "20200622104036256" }, // Filtering for specific docs
{ $set: { overAllStatus: "Started", "steps.$[element].status": "Open" } }, // Update specific element in an array
{ arrayFilters: [{ "element.name": { $in: ["Step Three", "Step Four"] } }] } // Returns specific elements in `steps` array that matches criteria for update
);
Ref : arrayfilters-for-an-array-update-operations
Note :
If you wanted to update overAllStatus field only in case where, for documents with executionId: "20200622104036256" and have at-least one step element with name either "Step Three" or "Step Four" - then your filter part of .updateMany() should be :
{"executionId" : "20200622104036256", 'steps.name': { $in : ["Step Three","Step Four"]}}

How to group multiple documents if an array within them contains an element which is present in another document's array?

I am trying to group multiple documents by addresses present in each document. However, the addresses are sub-documents themselves, and stored in an array. I require to group two documents together if they have even one same address present in their arrays, but not necessarily in the same index. Could this be done? The general structure of a document is as follows:
{
"_id" : ObjectId("5ccb0983258f7a1694f30e7d"),
"name" : {
"first" : "John",
"middle" : "J",
"last" : "Doe",
"prefix" : "Mr.",
"professionalSuffixes" : [
"MD"
],
"generationalSuffix" : "Jr"
},
"ssn" : "123-45-6789",
"birthDate" : "1996-06-28",
"gender" : "Unknown",
"maritalStatus" : "Separated",
"postalAddresses" : [
{
"streetAddress" : [
"23 LeeWay RD",
"APT 342"
],
"officeSuite" : "4743",
"apartmentNumber" : "022",
"postOfficeBoxNumber" : "12345",
"postalCode" : "12345",
"city" : "St Louis",
"state" : {
"code" : "MO",
"name" : "Missouri",
"description" : "Test Description"
},
"country" : {
"name" : "United States of America",
"iso2Code" : "US",
"iso3Code" : "USA",
"description" : "Test Description"
}
}
]
}
Thanks in advance.
Based on your comment responding to mine you just need to unwind the field first:
{
$unwind: "$postalAddresses"
},
{
$group: {
_id: group_cond,
docs_ids: {$push: "$_id"}
}
}
Now group condition should be whatever makes an address "unique",
it should look a little something like this:
{ country: "$postalAddresses.country.name", state: "$postalAddresses.state.code", city: "$postalAddresses.city", street: "$postalAddresses.street."}

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.

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();

MongoDB: Unable to find required records

I am new to MongoDB. And I have following collections in my MongoDB. My Problem is I am not able to make a find command which gives required facilities based on provided ID or Name.
Find command which I have tried BUT NOT working :-
db.mgh_facilities.find({facilities: {$elemMatch: {name: "Foreign exchange assistance"}}}).
For me its returning all the records. Shouldn't it be just returning { "id" : "11", "name" : "Foreign exchange assistance" }
My Collections:-
{
"_id" : ObjectId("548acc28ae6ff1c0fd1d7470"),
"responseCode" : "true",
"facilities" : [
{
"id" : "11",
"name" : "Foreign exchange assistance"
},
{
"id" : "12",
"name" : "Assistance with luggage on request"
},
{
"id" : "13",
"name" : "24 hours power back-up"
},
{
"id" : "14",
"name" : "A/C Power Backup Available"
},
{
"id" : "15",
"name" : "swimming pool"
},
{
"id" : "35",
"name" : "shoe cleaning service"
},
{
"id" : "36",
"name" : "Smoke detectors"
},
{
"id" : "37",
"name" : "Fire Extinguishers in each room"
},
{
"id" : "38",
"name" : "Pest Control"
},
{
"id" : "39",
"name" : "Conference / Banquet Hall"
},
{
"id" : "45",
"name" : "Restaurant"
},
{
"id" : "53",
"name" : "Anti-slip ramps"
},
{
"id" : "56",
"name" : "Tea/ Coffee Maker in the Rooms"
},
{
"id" : "59",
"name" : "Wi Fi Internet"
}
]
}
The find command has found the document which contains the facility object with a name matching your search. It doesn't know that you only want to see the single subdocument responsible for that document matching your search criteria.
You can tell mongo that you want to see that element with the positional $ operator.
db.mgh_facilities.find({"facilities.name": "Foreign exchange assistance"}, {"facilities.$": true})
You can try this
db.mgh_facilities.aggregate([
{
$unwind:"$facilities"
},
{
$match:{"facilities.name": "Foreign exchange assistance"}
},{
$project:{
_id:0,
facilities:1
}
}
])
result:
{
"result" : [
{
"facilities" : {
"id" : "11",
"name" : "Foreign exchange assistance"
}
}
],
"ok" : 1
}