Not able to perform Deep Insert operation for API_PRODUCT_SRV Standard WhiteListed API using S/4 Hana Cloud SDK - s4sdk

I have completed read and update operations on API_PRODUCT_SRV Service.
Now while doing deep insert on API_PRODUCT_SRV (Product Entity-which has many associations) I am getting the following error.
“errordetails”: [
{
“code”: “API_PRD_MSG/004”,
“message”: “Provide atleast one description for the product.”,
“propertyref”: “”,
“severity”: “error”,
“target”: “”
}
]
I found this deep dive blog
https://blogs.sap.com/2017/12/07/step-20-with-s4hana-cloud-sdk-create-and-deep-insert-with-the-virtual-data-model-for-odata/comment-page-1/#comment-453020
which explains the deep insert using servlets.(i.e Using HttpServletReq) which provides the rest service.
But I am using the CreateRequest class from SAP Cloud Application Programming Model which generates odata service, so that I cannot use the similar code which is presented in the blog.
I have added the code and the payload for your perusal.
Create Operation code
#Create(serviceName = "ProductService", entity = "Products")
public CreateResponse create(CreateRequest req) throws ODataException {
Product toCreate = new ModelMapper().map(req.getMapData(), Product.class);
Product created = new DefaultProductMasterService().createProduct(toCreate)
.execute(new ErpConfigContext("K4XS4SDKDest"));
return CreateResponse.setSuccess().setData(created).response();
}
Payload being used:
{
"Product" : "BALL",
"ProductType" : "ZHLB",
"CrossPlantStatus" : "",
"CrossPlantStatusValidityDate" : null,
"CreationDate" : "\/Date(1499731200000)\/",
"CreatedByUser" : "11279380",
"LastChangeDate" : "\/Date(1550448000000)\/",
"LastChangedByUser" : "HWV87616",
"IsMarkedForDeletion" : false,
"ProductOldID" : "",
"GrossWeight" : "0.000",
"PurchaseOrderQuantityUnit" : "",
"SourceOfSupply" : "",
"WeightUnit" : "KG",
"NetWeight" : "0.000",
"CountryOfOrigin" : "",
"CompetitorID" : "",
"ProductGroup" : "01",
"BaseUnit" : "EA",
"ItemCategoryGroup" : "",
"ProductHierarchy" : "",
"Division" : "",
"VarblPurOrdUnitIsActive" : "",
"VolumeUnit" : "",
"MaterialVolume" : "0.000",
"ANPCode" : "0",
"Brand" : "",
"ProcurementRule" : "",
"ValidityStartDate" : null,
"LowLevelCode" : "",
"ProdNoInGenProdInPrepackProd" : "",
"SerialIdentifierAssgmtProfile" : "",
"SizeOrDimensionText" : "",
"IndustryStandardName" : "",
"ProductStandardID" : "",
"InternationalArticleNumberCat" : "",
"ProductIsConfigurable" : false,
"IsBatchManagementRequired" : false,
"ExternalProductGroup" : "",
"CrossPlantConfigurableProduct" : "",
"SerialNoExplicitnessLevel" : "",
"ManufacturerPartProfile" : "",
"ChangeNumber" : "",
"MaterialRevisionLevel" : "",
"HandlingIndicator" : "",
"WarehouseProductGroup" : "",
"WarehouseStorageCondition" : "",
"StandardHandlingUnitType" : "",
"SerialNumberProfile" : "",
"AdjustmentProfile" : "",
"PreferredUnitOfMeasure" : "",
"IsPilferable" : false,
"IsRelevantForHzdsSubstances" : false,
"QuarantinePeriod" : "0",
"TimeUnitForQuarantinePeriod" : "",
"QualityInspectionGroup" : "",
"AuthorizationGroup" : "",
"HandlingUnitType" : "",
"HasVariableTareWeight" : false,
"MaximumPackagingLength" : "0.000",
"MaximumPackagingWidth" : "0.000",
"MaximumPackagingHeight" : "0.000",
"to_Description": {
"results": [
{
"Product" : "BALL",
"Language" : "EN",
"ProductDescription" : "Pipes for machines"
}
]
}
}
Can u please help me how shall I modify my code to make deep insert with SAP S/4HANA Cloud SDK work while using SAP Cloud Application Programming Model (CreateRequest class)?
Log file:
Product(super=VdmObject(customFields={}, changedOriginalFields={LowLevelCode=null, ProductGroup=null, SizeOrDimensionText=null, CreatedByUser=null, CountryOfOrigin=null, Product=null, ProductStandardID=null, IsPilferable=null, VolumeUnit=null, WarehouseProductGroup=null, WarehouseStorageCondition=null, MaterialVolume=null, ManufacturerPartProfile=null, CrossPlantStatus=null, TimeUnitForQuarantinePeriod=null, GrossWeight=null, InternationalArticleNumberCat=null, SourceOfSupply=null, ProductType=null, ItemCategoryGroup=null, ProcurementRule=null, BaseUnit=null, ProductOldID=null, VarblPurOrdUnitIsActive=null, LastChangedByUser=null, Brand=null, MaximumPackagingWidth=null, QuarantinePeriod=null, PurchaseOrderQuantityUnit=null, ProductHierarchy=null, AuthorizationGroup=null, StandardHandlingUnitType=null, MaterialRevisionLevel=null, ExternalProductGroup=null, CrossPlantConfigurableProduct=null, MaximumPackagingLength=null, HasVariableTareWeight=null, ANPCode=null, ProdNoInGenProdInPrepackProd=null, WeightUnit=null, IsMarkedForDeletion=null, CompetitorID=null, QualityInspectionGroup=null, IsBatchManagementRequired=null, IsRelevantForHzdsSubstances=null, Division=null, SerialIdentifierAssgmtProfile=null, AdjustmentProfile=null, PreferredUnitOfMeasure=null, SerialNoExplicitnessLevel=null, HandlingIndicator=null, HandlingUnitType=null, NetWeight=null, ProductIsConfigurable=null, IndustryStandardName=null, SerialNumberProfile=null, ChangeNumber=null, MaximumPackagingHeight=null}), product=BELL, productType=ZHLB, crossPlantStatus=, crossPlantStatusValidityDate=null, creationDate=null, createdByUser=11279380, lastChangeDate=null, lastChangedByUser=HWV87616, lastChangeDateTime=null, isMarkedForDeletion=false, productOldID=, grossWeight=0.000, purchaseOrderQuantityUnit=, sourceOfSupply=, weightUnit=KG, netWeight=0.000, countryOfOrigin=, competitorID=, productGroup=01, baseUnit=EA, itemCategoryGroup=, productHierarchy=, division=, varblPurOrdUnitIsActive=, volumeUnit=, materialVolume=0.000, aNPCode=0, brand=, procurementRule=, validityStartDate=null, lowLevelCode=, prodNoInGenProdInPrepackProd=, serialIdentifierAssgmtProfile=, sizeOrDimensionText=, industryStandardName=, productStandardID=, internationalArticleNumberCat=, productIsConfigurable=false, isBatchManagementRequired=false, externalProductGroup=, crossPlantConfigurableProduct=, serialNoExplicitnessLevel=, productManufacturerNumber=null, manufacturerNumber=null, manufacturerPartProfile=, changeNumber=, materialRevisionLevel=, handlingIndicator=, warehouseProductGroup=, warehouseStorageCondition=, standardHandlingUnitType=, serialNumberProfile=, adjustmentProfile=, preferredUnitOfMeasure=, isPilferable=false, isRelevantForHzdsSubstances=false, quarantinePeriod=0, timeUnitForQuarantinePeriod=, qualityInspectionGroup=, authorizationGroup=, handlingUnitType=, hasVariableTareWeight=false, maximumPackagingLength=0.000, maximumPackagingWidth=0.000, maximumPackagingHeight=0.000, erpConfigContext=null, toDescription=null, toPlant=null, toProductBasicText=null, toProductInspectionText=null, toProductProcurement=null, toProductPurchaseText=null, toProductQualityMgmt=null, toProductSales=null, toProductSalesTax=null, toProductStorage=null, toProductUnitsOfMeasure=null, toSalesDelivery=null)
{ "written_at":"2019-03-11T03:56:27.923Z","written_ts":918343802814688,"component_id":"e8c99eff-1a4e-4266-ba2a-fc099399100c","component_name":"FNpy7mXtvln0dnT1-FinalTestApp-srv","DCComponent":"","organization_name":"-","component_type":"application","space_name":"dev","component_instance":"0","organization_id":"-","correlation_id":"-","CSNComponent":"","space_id":"a78252bf-72bf-479c-b761-8260de0c776e","Application":"FNpy7mXtvln0dnT1-FinalTestApp-srv","container_id":"10.0.138.113","type":"log","logger":"com.sap.cloud.sdk.service.prov.api.util.ProcessorHelper","thread":"http-nio-0.0.0.0-3000-exec-7","level":"ERROR","categories":[],"msg":"The endpoint responded with HTTP error code 400.\nProvide atleast one description for the product.\nFull error message: \n{\n \"error\": {\n \"code\": \"API_PRD_MSG/004\",\n \"message\": {\n \"lang\": \"en\",\n \"value\": \"Provide atleast one description for the product.\"\n },\n \"innererror\": {\n \"application\": {\n \"component_id\": \"LO-MD-MM\",\n \"service_namespace\": \"/SAP/\",\n \"service_id\": \"API_PRODUCT_SRV\",\n \"service_version\": \"0001\"\n },\n \"transactionid\": \"C16DD240C7520010E005C7E648BC12F5\",\n \"timestamp\": \"20190311035627.5989630\",\n \"Error_Resolution\": {\n \"SAP_Transaction\": \"For backend administrators: run transaction /IWFND/ERROR_LOG on SAP Gateway hub system and search for entries with the timestamp above for more details\",\n \"SAP_Note\": \"See SAP Note 1797736 for error analysis (https://service.sap.com/sap/support/notes/1797736)\"\n },\n \"errordetails\": [\n {\n \"code\": \"API_PRD_MSG/004\",\n \"message\": \"Provide atleast one description for the product.\",\n \"propertyref\": \"\",\n \"severity\": \"error\",\n \"target\": \"\"\n }\n ]\n }\n }\n}","stacktrace":["java.lang.reflect.InvocationTargetException","\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)","\tat
my-service.cds
using API_PRODUCT_SRV from '../srv/external/csn/API_PRODUCT_SRV.json';
service ProductService {
entity Products as Projection on API_PRODUCT_SRV.A_ProductType {
key Product,
ProductType,
CreationDate,
CrossPlantStatus,
CrossPlantStatusValidityDate,
CreatedByUser,
LastChangeDate,
LastChangedByUser,
IsMarkedForDeletion,
ProductOldID,
GrossWeight,
PurchaseOrderQuantityUnit,
SourceOfSupply,
WeightUnit,
NetWeight,
CountryOfOrigin,
CompetitorID,
ProductGroup,
BaseUnit,
ItemCategoryGroup,
ProductHierarchy,
Division,
VarblPurOrdUnitIsActive,
VolumeUnit,
MaterialVolume,
ANPCode,
Brand,
ProcurementRule,
ValidityStartDate,
LowLevelCode,
ProdNoInGenProdInPrepackProd,
SerialIdentifierAssgmtProfile,
SizeOrDimensionText,
IndustryStandardName,
ProductStandardID,
InternationalArticleNumberCat,
ProductIsConfigurable,
IsBatchManagementRequired,
ExternalProductGroup,
CrossPlantConfigurableProduct,
SerialNoExplicitnessLevel,
ProductManufacturerNumber,
ManufacturerPartProfile,
ChangeNumber,
MaterialRevisionLevel,
HandlingIndicator,
WarehouseProductGroup,
WarehouseStorageCondition,
StandardHandlingUnitType,
SerialNumberProfile,
AdjustmentProfile,
PreferredUnitOfMeasure,
IsPilferable,
IsRelevantForHzdsSubstances,
QuarantinePeriod,
TimeUnitForQuarantinePeriod,
QualityInspectionGroup,
AuthorizationGroup,
HandlingUnitType,
HasVariableTareWeight,
MaximumPackagingLength,
MaximumPackagingWidth,
MaximumPackagingHeight,
to_Description
}
entity A_ProductDescriptionType as Projection on API_PRODUCT_SRV.A_ProductDescriptionType
{
key Product,
key Language,
ProductDescription
}
}
Can u please tell how to add associations in it?
my-service.cds
using API_BUSINESS_PARTNER as bp from './external/csn/API_BUSINESS_PARTNER';
service CrudService{
#cds.persistence.skip
Entity BusinessPartner as projection on bp.A_BusinessPartnerType{
BusinessPartner,
LastName,
FirstName,
BusinessPartnerCategory
};
}
Warm regards,
Meenakshi

Can you please share your entire project if possible. The request map may not be containing the product description data because I guess the association between the product and description is not defined properly in the CDS file.
Please check the following documentation to define your entities and associations:
https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/855e00bd559742a3b8276fbed4af1008.html
I am interested in knowing what is the $metadata response for your service currently. Also, I would like to see your custom handler code and how you are trying to retrieve the deep insert payload from the request object.
Thanks,
Kranti

The problem is your JSON request payload:
{
"Product" : "BALL",
...
"to_Description": {
"results": [
{
"Product" : "BALL",
"Language" : "EN",
"ProductDescription" : "Pipes for machines"
}
]
}
}
to_Description is not expected to be an object. Instead it should be an array:
{
"Product" : "BALL",
...
"to_Description": [
{
"Product" : "BALL",
"Language" : "EN",
"ProductDescription" : "Pipes for machines"
}
]
}

Related

Spring - How to correctly show relationship data in view (table) using REST api

I have a User (id, username) entity which has many-to-many relationship with Roles (id, name) entity. I am trying to show the User data in a ajax Datatable. Now, if a User has six roles, it shows six [object Object] for all six roles. I dont know how to correctly show the role name instead of object Object.
This is what I have:
.DataTable(
{
"pagingType" : "full_numbers",
"sAjaxSource" : "/api/AppUser/all",
"sAjaxDataProp" : "",
"aoColumns" : [
{
"data" : "id"
},
{
"data" : "username"
},
{
"data" : "userenabled"
},
{
"data" : "useremail"
},
{
"data" : "userfirstname"
},
{
"data" : "userlastname"
},
{
"data" : "useraddress"
},
{
"data" : "roles"
}
This is how it looks like in Data Table:
Here is my REST Controller piece:
#RestController
#RequestMapping("/api/AppUser")
public class AppUserRestAPIs {
#GetMapping(value = "/all", produces = "application/json")
public List<AppUser> getResource() {
return appUserJPARepository.findAll();
}
}
I know it must be trivial but feeling lost and could not find a single example on how to represent relationship data in view (html) using REST api. Searched almost everywhere. What I am missing here? Will appreciate any pointers here.
Answering my own question:
Found it ! Here - https://editor.datatables.net/examples/advanced/joinArray.html
So instead of:
{
"data" : "roles"
}
I have to use:
{
"data" : "roles",
render : "[, ].name"
}
All worked perfectly but now I am clueless what if I don't use Datatable. Not sure if I have to put another question for it.
Use function to flat roles list:
Instead of
{
"data" : "roles"
}
Try this :
{
"data": null,
"render": function(data, type, row, meta) {
var flatrole = '';
//loop through all the roles to build output string
for (var role in data.roles) {
flatrole = flatrole + role.name + " ";
}
return flatrole;
}
}

Unwrapping a Kotlin hashmap in Thymeleaf inside of Spring Boot 2

I have a Kotlin function which creates a model with a hashmap as shown below
#GetMapping("/")
fun index(model: Model): Mono<String> {
model.addAttribute("images", imageService.findAllImages()?.flatMap { image ->
Mono.just(image)
.zipWith(repository.findByImageId(image?.id!!).collectList())
.map({ imageAndComments: Tuple2<Image?, MutableList<learningspringboot.images.Comment>> ->
hashMapOf<String, Any?>(
"id" to imageAndComments.t1?.id,
"name" to imageAndComments.t1?.name,
"comments" to imageAndComments.t2)
}).log("findAllImages")
})
model.addAttribute("extra", "DevTools can also detech code changes.")
return Mono.just("index")
}
Image.kt
package learningspringboot.images
import org.springframework.data.annotation.Id
data class Image(#Id var id: String? = null, var name: String? = null)
Comment.kt
package learningspringboot.images
import org.springframework.data.annotation.Id
data class Comment #JvmOverloads constructor(#Id private var id: String? = null, private var imageId: String? = null, private var comment: String? = null) {
}
In my Thymeleaf template I have
<ul><li th:each = "Comment :${image.comments}" th:text = "${image.comments}"></li></ul>
Which gives me this lines like
[Comment(id=5a623d5d2298352bc4929866, imageId=0d46b575-b6ce-48e2-988a-ebe62ebc2ceb, comment=test), Comment(id=5a623d8b2298352bc4929867, imageId=0d46b575-b6ce-48e2-988a-ebe62ebc2ceb, comment=test23)]
Which shows the comment record as is with the MongoDB keys/ids and everything else. This is not what I want.
I also have this in my Thymeleaf template
<ul><li th:each = "Comment :${image.comments}" th:text = "${comment == null ? 'empty' : comment.Comment}"></li></ul>
Which shows the word empty for each comment record.
The comment record in the database looks like
{ "_id" : ObjectId("5a623d5d2298352bc4929866"), "imageId" : "0d46b575-b6ce-48e2-988a-ebe62ebc2ceb", "comment" : "test", "_class" : "learningspringboot.comments.Comment" }
The image records in the database looks like
{ "_id" : ObjectId("5a623d5d2298352bc4929866"), "imageId" : "0d46b575-b6ce-48e2-988a-ebe62ebc2ceb", "comment" : "test", "_class" : "learningspringboot.comments.Comment" }
{ "_id" : ObjectId("5a623d8b2298352bc4929867"), "imageId" : "0d46b575-b6ce-48e2-988a-ebe62ebc2ceb", "comment" : "test23", "_class" : "learningspringboot.comments.Comment" }
How can I unwrap the comments records so that I only see the "comment" values and not the "_id" or "imageId" values?
The problem is that I have a hashmap<string>,arraylist<image>.
So I simply need to loop through all the image elements in the array list using thymeleaf. I'm pretty sure that this has been done before, I'll just need to find a good example and do some reading.
I was able to use the following code
<th:block th:each="Comment : ${image.comments}">
<ul th:each="comment : ${Comment}">
<li th:text="${comment.comment}"></li>
</ul>
</th:block>
And now I can move on.

missing type in composite literal in golang/mongodb aggregate query

I want to write mongo query in golang. my mongo query is -
aggregate([
{$match: {$and :
[
{"stream" : "CS"},
{"semester" : "sem3"},
{"section" : "A"}
]
}},
{$unwind: '$atndnc'},
{ $group: { _id:{rollno: "$atndnc.rollno",attend:"$atndnc.attend"},count: { $sum: 1 }}},
{ $project:
{ _id: '$_id.rollno',
'attend' : '$_id.attend',
'count' : '$count'
}}
])
And my Go code is -
cond:=[]bson.M{
bson.M{"$match": bson.M{"$and ":[]interface{}{
bson.M{"stream" : srchobj.Stream},
bson.M{"semester" : srchobj.Semester},
bson.M{"section" : srchobj.Section},
bson.M{"college_id":srchobj.College_id},
bson.M{"date":bson.M{"$gt":srchobj.Startdate,"$lt":srchobj.Enddate}}}}},
bson.M{"$unwind": "$atndnc"},
bson.M{"$group":bson.M{"_id":{"rollno":bson.M{"$atndnc.rollno"},"attend":bson.M{"$atndnc.attend"}},"count":bson.M{"$sum":1}}},
bson.M{"$project":bson.M{"_id":"$_id.rollno","count":"$_id.count"}}}
but it give the error "missing type in composite literal" in
bson.M{"$group":bson.M{"_id":{"rollno":bson.M{"$atndnc.rollno"},"attend":bson.M{"$atndnc.attend"}},"count":bson.M{"$sum":1}}},
in this line.what should i do now?
You have a missing type declaration on a set of braces in your $group query:
{"rollno":bson.M{"$atndnc.rollno"},"attend":bson.M{"$atndnc.attend"}}
I would assume should be:
bson.M{"rollno":bson.M{"$atndnc.rollno"},"attend":bson.M{"$atndnc.attend":nil}}
there are also a few other initialization things like initializations with just a string key (remember, a bson.M is just an alias for map[string]interface{}
Thanks for your support.I got the desired output by doing this.
cond :=[]bson.M{
bson.M{"$match": bson.M{
"stream" : srchobj.Stream,
"semester" : srchobj.Semester,
"section" : srchobj.Section,
"college_id":srchobj.College_id,
"date":bson.M{
"$gt":srchobj.Startdate,
"$lt":srchobj.Enddate},
},
},
bson.M{"$unwind": "$atndnc"},
bson.M{"$group":bson.M{
"_id":bson.M{
"rollno":"$atndnc.rollno",
"attend":"$atndnc.attend",
"name":"$atndnc.name",
},
"count":bson.M{"$sum":1},
},
},
bson.M{"$project":bson.M{
"rollno":"$_id.rollno",
"name":"$_id.name",
"count":"$count",
"attend":"$_id.attend",
},
},
bson.M{"$sort":bson.M{"rollno":1}},
}

How to add HATEOAS links in a sub resource

I have a parent resource called the AdminResource and a child resource called the AdminModuleResource.
The resource of the parent is correctly fitted with HATEOAS links:
{
"firstname" : "Stephane",
"lastname" : "Eybert",
"email" : "mittiprovence#yahoo.se",
"password" : "e41de4c55873f9c000f4cdaac6efd3aa",
"passwordSalt" : "7bc7bf5f94fef7c7106afe5c3a40a2",
"links" : [ {
"rel" : "self",
"href" : "http://localhost/admins/3683"
}, {
"rel" : "modules",
"href" : "http://localhost/admins/3683/modules"
} ],
"id" : 3683
}
The resource of the child is also correctly fitted with HATEOAS links:
{
"module" : "BTS",
"adminResource" : {
"firstname" : "Stephane",
"lastname" : "Eybert",
"email" : "mittiprovence#yahoo.se",
"password" : "e41de4c55873f9c000f4cdaac6efd3aa",
"passwordSalt" : "7bc7bf5f94fef7c7106afe5c3a40a2",
"links" : [ ],
"id" : 3683
},
"links" : [ {
"rel" : "self",
"href" : "http://localhost/modules"
} ],
"id" : 1087
}
But its parent resource has lost its links.
For now, when inside my child admin module resource, the parent admin resource does not have its links. Indeed the toResource method of the assembler only provides the links for the child admin module resource.
public AdminModuleResource toResource(AdminModule adminModule) {
AdminModuleResource adminModuleResource = new AdminModuleResource();
adminModuleResource.fromAdminModule(adminModule);
adminModuleResource.add(linkTo(AdminModuleController.class).slash(adminModuleResource.getId()).withSelfRel());
return adminModuleResource;
}
public AdminResource toResource(Admin admin) {
AdminResource adminResource = createResourceWithId(admin.getId(), admin);
adminResource.fromAdmin(admin);
adminResource.add(linkTo(AdminController.class).slash(admin.getId()).slash(UriMappingConstants.MODULES).withRel(UriMappingConstants.MODULES));
return adminResource;
}
Any idea how I can add the links to the parent admin resource even when inside the child admin module resource ?
EDIT: Here is how I build the resources:
public void fromAdminModule(AdminModule adminModule) {
this.setResourceId(adminModule.getId());
this.setModule(adminModule.getModule());
AdminResource adminResource = new AdminResource();
adminResource.fromAdmin(adminModule.getAdmin());
this.adminResource = adminResource;
}
public void fromAdmin(Admin admin) {
this.setResourceId(admin.getId());
this.setFirstname(admin.getFirstname());
this.setLastname(admin.getLastname());
this.setEmail(admin.getEmail().toString());
this.setPassword(admin.getPassword());
}
Thanks !
Stephane
Just stumbled on this question, even though it is quite old, but may be worth answering for others implementing similar functionality. Basically, you create embedded resources for AdminModuleResource on your AdminResource and build the links for these embedded resources within your AdminResourceAssembler. The code below is a simplified version of what is posted on this answer
On AdminResource add:
#JsonUnwrapped
private Resources<EmbeddedWrapper> embeddeds;
// + setters/getters
On AdminResourceAssembler add:
EmbeddedWrappers wrapper = new EmbeddedWrappers(true);
List<EmbeddedWrapper> wrappers = (List<EmbeddedWrapper>) super.buildEmbeddables(entity);
Set<AdminModuleResource> moduleResources = adminResource.getModuleResources( );
if(!moduleResources.isEmpty( ))
wrappers.add(wrapper.wrap(adminModuleResourceAssembler.toResources(moduleResources)));
adminResource.setEmbeddeds(new Resources<>(wrappers));

update in a nested array using C# Driver in MongoDB

Here is my exact schema:
{
"_id" : ObjectId("4fb4fd04b748611ca8da0d45"),
"Name" : "Agent name",
"City" : "XXXX",
"BranchOffice" : [{
"_id" : ObjectId("4fb4fd04b748611ca8da0d46"),
"Name" : "Branch name",
"City" : "XXXX",
"SubBranch" : [{
"_id" : ObjectId("4fb4fd04b748611ca8da0d47"),
"Name" : "Sub-Branch Name",
"City" : "XXXX"
"Users" : [{
"_id" : ObjectId("4fb4fd04b748611ca8da0d48"),
"Name" : "User",
"City" : "XXXX"
}]
}]
}]
}
Its Inserted successfully in c#. insert code was below but update condition is failed .
I want to update field 3 level and 4 level of array using SubBranch and users
Insert code
IMongoQuery query = Query.And(Query.EQ("_id", new ObjectId(4fb4fd04b748611ca8da0d45)),
Query.EQ("BranchOffice._id", new ObjectId(4fb4fd04b748611ca8da0d46)));
Agent agent = dc.Collection.FindOne(query);
BsonDocument branchOffice = agent.BranchOffice.Find(objId => objId._id == new ObjectId(4fb4fd04b748611ca8da0d46)).ToBsonDocument();
subBranch I had get List object convert to BsonDocument
Files: name,city,_Id, and users for array
BsonDocument subBranchOffice = **subBranch.ToBsonDocument()**;
if (branchOffice.Contains("SubBranch"))
{
if (branchOffice["SubBranch"].IsBsonNull)
{
branchOffice["SubBranch"] = new BsonArray().Add(BsonValue.Create(subBranchOffice));
}
else
{
branchOffice["SubBranch"].AsBsonArray.Add(BsonValue.Create(subBranchOffice));
}
var update = Update.Set("BranchOffice.$.SubBranch",branchOffice["SubBranch"]);
SafeModeResult s = dc.Collection.Update(query, update, UpdateFlags.Upsert,SafeMode.True);
}
Here SafemodeResult is UpdateExisting = true
Here Inserted Option is successfully
next I try to update in else Statement. I am not get it answer
Update code
else
{
var queryEdit = Query.And(Query.EQ("_id", new ObjectId(4fb4fd04b748611ca8da0d45)),
Query.EQ("BranchOffice._id", new ObjectId(4fb4fd04b748611ca8da0d46)),
Query.EQ("SubBranchlist._id", new ObjectId(4fb4fd04b748611ca8da0d47)));
**//Index value 1 or 2 or 3**
var update = Update.Set("BranchOffice.$.SubBranch."index value".Name", "sname").
Set("BranchOffice.$.SubBranch."index value".city", "yyyyy" ?? string.Empty);
SafeModeResult s = dc.Collection.Update(queryEdit, update, UpdateFlags.None,SafeMode.True);
}
Here SafemodeResult is UpdateExisting = False
Here updated Option is fail
Please explain how to solve this probelm and how to update field 2 and 3 level of array
Please show any Example
There's a lot there, but it looks like at least part of your problem is that you've spelled BranchOffice differently between the data and the query you are using to update, also you've missed the hierarchy in SubBranch, so your queryEdit in the last code sample won't match the document. This will;
db.so.find({
_id: ObjectId("4fb4fd04b748611ca8da0d45"),
"BrancheOffice._id": ObjectId("4fb4fd04b748611ca8da0d46"),
"BrancheOffice.SubBranch._id": ObjectId("4fb4fd04b748611ca8da0d47"),
}).toArray()

Resources