fetch value from SharePoint JSON output - azure-logic-apps

I am getting below JSON object from sharepoint list. how can I get the value for Company in the Data operation ( select) for logic apps. I did item()['Company']?['Value'] and it is not working. Any suggestions?
"body": [
{
"Company": {
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference",
"Id": 0,
"Value": "Test1"
},
"Date From": "2022-03-30",
"Date To": "2022-03-31",
"Title": "Title 1"
},
{
"Company": {
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference",
"Id": 2,
"Value": "Line2"
},
"Date From": "2022-03-21",
"Date To": "2022-03-29",
"Title": "Title 2"
}
]
}
I am fetching share-point list and then using data operations (select) to get the JSON as output.
I need JSON in the below format so that I can pass this to store proc and insert into the Azure SQL DB. I have another 12 items in the list.
[
{
"Company": "Test1",
"Date From": "2022-03-30",
"Date To": "2022-03-31",
"Title": "Title 1"
},
{
"Company": "Line2",
"Date From": "2022-03-21",
"Date To": "2022-03-29",
"Title": "Title 2"
}
]

Rather than select, you can set a variable. We're all different but that makes far more sense to me.
Your expression is much the same, I used ...
item()['Company']['Value']
Just make sure you initialise the variable outside and prior to the For each ...
This is the result for the first item in the array ...
To compile a full JSON object and add it to an array, again, simply use a variable and specify the values as need be.
Firstly, initialize your array outside of the For each ...
... and then in the For each, add an object to the array variable on each loop (make sure you include the quotes around the expression where required) ...
You just have to compile the JSON. The end result will look like this ...
This is the JSON in full ...
[
{
"Company": "Line2",
"Date From": "2022-03-21",
"Date To": "2022-03-29",
"Title": "Title 2"
},
{
"Company": "Test1",
"Date From": "2022-03-30",
"Date To": "2022-03-31",
"Title": "Title 1"
}
]
Also, you'll notice my list has come out in a different order, that's because the For each runs in parallel, if you need to avoid that, change the settings so it runs in a single thread ...
This is the JSON definition of the LogicApp, you can load it into your tenant and test with it ...
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"For_each": {
"actions": {
"Append_to_SQL_Array": {
"inputs": {
"name": "SQL Array",
"value": {
"Company": "#{item()['Company']['Value']}",
"Date From": "#{item()['Date From']}",
"Date To": "#{item()['Date To']}",
"Title": "#{item()['Title']}"
}
},
"runAfter": {},
"type": "AppendToArrayVariable"
}
},
"foreach": "#variables('SharePoint JSON')",
"runAfter": {
"Initialize_SQL_Array": [
"Succeeded"
]
},
"runtimeConfiguration": {
"concurrency": {
"repetitions": 1
}
},
"type": "Foreach"
},
"Initialize_SQL_Array": {
"inputs": {
"variables": [
{
"name": "SQL Array",
"type": "array"
}
]
},
"runAfter": {
"Initialize_SharePoint_JSON": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_SharePoint_JSON": {
"inputs": {
"variables": [
{
"name": "SharePoint JSON",
"type": "array",
"value": [
{
"Company": {
"Id": 0,
"Value": "Test1",
"odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference"
},
"Date From": "2022-03-30",
"Date To": "2022-03-31",
"Title": "Title 1"
},
{
"Company": {
"Id": 2,
"Value": "Line2",
"odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference"
},
"Date From": "2022-03-21",
"Date To": "2022-03-29",
"Title": "Title 2"
}
]
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "Result",
"type": "array",
"value": "#variables('SQL Array')"
}
]
},
"runAfter": {
"For_each": [
"Succeeded"
]
},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"Recurrence": {
"evaluatedRecurrence": {
"frequency": "Month",
"interval": 12
},
"recurrence": {
"frequency": "Month",
"interval": 12
},
"type": "Recurrence"
}
}
},
"parameters": {}
}

Related

Azure Logic app access json property depending on value

I'm trying to get a list of reviews from an api.
This gives me a JSON with nested properties.
I manage to get almost all the data I need except from the nested array ["value"]["answers"]["value"] because sometimes the array ["answers"] has one item (with "id" being either "goods", "delivery" or "service"), or 2 or all 3 of them.
So I can't use the index to get what I want.
I need to be able to check the "id" and from that append the "value" to my array.
Is there a way to write an expression that checks the "id" and from then on writes the "value" in my array ?
JSON :
...
"surveyData": [
{
"questionRef": "q1",
"type": "CORE_STAR_RATING",
"properties": {
"title": "How do you evaluate ...?"
},
"value": {
"stars": 5,
"notAnswered": false
},
"userDefinedId": "q1"
},
"userDefinedId": "q2-good"
},
{
"questionRef": "q3",
"type": "DIMENSIONS",
"properties": {
"title": "How do you evaluate on those criterias ?"
},
**"value": {
"answers": [
{
"id": "delivery",
"value": 4,
"userDefinedId": "delivery",
"name": "Delivery",
"firstLabel": "Nul",
"lastLabel": "Good"
},
{
"id": "goods",
"value": 5,
"userDefinedId": "goods",
"name": "Goods",
"firstLabel": "Nul",
"lastLabel": "Good"
},
{
"id": "service",
"value": 5,
"userDefinedId": "service",
"name": "Service",
"firstLabel": "Nul",
"lastLabel": "Good"
}
]**
},
"userDefinedId": "q3-group"
}
]
...
My array so far :
"value": {
"Event": "#items('For_each-Service')?['event']?['type']",
"Delivery": "", <= ??
"Goods": "", <= ??
"Service": "#items('For_each-Service')?['surveyData'][2]?['value']?['answers'][2]?['value']", <= doesn't work
"comment": "#items('For_each-Service')?['reply']?['comment']",
"order date": "#items('For_each-Service')?['transaction']?['date']",
"date": "#items('For_each-Service')?['reply']?['createdAt']",
"email": "#items('For_each-Service')?['customer']?['email']",
"id review": "#items('For_each-Service')?['event']?['id']",
"name client": "#items('For_each-Service')?['customer']?['fullName']",
"status": "#items('For_each-Service')?['state']",
"title": "#items('For_each-Service')?['title']"
}
Thank you
There are a couple of ways to skin this cat, some more efficient than others.
Personally, I would take the following approach.
I created a flow where, basically, the first thing it does is initialise a variable that contains your Answers array as the data ...
The next step is to initialize another variable that stores that array as XML ...
This is the expression contained within ...
xml(json(concat('{ "root": { "answer": ', variables('Answers Array'), '}}')))
In the next step, I'm basically doing what you're doing by constructing an object, only this time, the selection for the values are a little more complex, this is the definition of the body ...
{
"Delivery": #{first(xpath(xml(variables('XML')), '//id[contains(text(), "delivery")]/parent::answer/value/text()'))},
"Goods": #{first(xpath(xml(variables('XML')), '//id[contains(text(), "goods")]/parent::answer/value/text()'))},
"Service": #{first(xpath(xml(variables('XML')), '//id[contains(text(), "service")]/parent::answer/value/text()'))}
}
Using the xpath approach for querying the dataset can cut down the amount of steps you need to take to get the desired result.
If an element is missing, it will simply come back as null ...
Below is one of the workarounds to achieve your requirement. Firstly, I have initialised 3 variables for Delivery, Goods and Service Counts.
Then used Parse_JSON to extract the inner values of the JSON provided.
In the next step I'm trying to iterate through Id's using Switch action with body('Parse_JSON')?['value']?['answers']?[iterationIndexes('Until')]?['id'] expression and set the variables using below expression inside an until loop.
body('Parse_JSON')?['value']?['answers']?[iterationIndexes('Until')]?['value']
and finally you can add in your array like below
RESULTS:
You can use below code view to reproduce in your logic app
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": {
"value": {
"answers": [
{
"firstLabel": "Nul",
"id": "goods",
"lastLabel": "Good",
"name": "Goods",
"userDefinedId": "goods",
"value": 4
},
{
"firstLabel": "Nul",
"id": "service",
"lastLabel": "Good",
"name": "Service",
"userDefinedId": "service",
"value": 5
}
]
}
},
"runAfter": {
"Initialize_variable_Service_Count": [
"Succeeded"
]
},
"type": "Compose"
},
"Compose_2": {
"inputs": " \"value\": {\n \"Event\": \"#items('For_each-Service')?['event']?['type']\",\n \"Delivery\": \"#{variables('Delivery Count')}\", \n \"Goods\": \"#{variables('Goods Count')}\", \n \"Service\": \"#{variables('Service Count')}\"\n }",
"runAfter": {
"Until": [
"Succeeded"
]
},
"type": "Compose"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "i",
"type": "integer",
"value": 0
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Initialize_variable_Delivery_count": {
"inputs": {
"variables": [
{
"name": "Delivery Count",
"type": "integer"
}
]
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_Goods_Count": {
"inputs": {
"variables": [
{
"name": "Goods Count",
"type": "integer"
}
]
},
"runAfter": {
"Initialize_variable_Delivery_count": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_Service_Count": {
"inputs": {
"variables": [
{
"name": "Service Count",
"type": "integer"
}
]
},
"runAfter": {
"Initialize_variable_Goods_Count": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Parse_JSON": {
"inputs": {
"content": "#outputs('Compose')",
"schema": {
"properties": {
"value": {
"properties": {
"answers": {
"items": {
"properties": {
"firstLabel": {
"type": "string"
},
"id": {
"type": "string"
},
"lastLabel": {
"type": "string"
},
"name": {
"type": "string"
},
"userDefinedId": {
"type": "string"
},
"value": {
"type": "integer"
}
},
"required": [],
"type": "object"
},
"type": "array"
}
},
"type": "object"
}
},
"type": "object"
}
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "ParseJson"
},
"Until": {
"actions": {
"Increment_variable": {
"inputs": {
"name": "i",
"value": 1
},
"runAfter": {
"Switch": [
"Succeeded"
]
},
"type": "IncrementVariable"
},
"Switch": {
"cases": {
"Case_Delivery": {
"actions": {
"Set_variable_Delivery_Count": {
"inputs": {
"name": "Delivery Count",
"value": "#body('Parse_JSON')?['value']?['answers']?[iterationIndexes('Until')]?['value']"
},
"runAfter": {},
"type": "SetVariable"
}
},
"case": "delivery"
},
"Case_Goods": {
"actions": {
"Set_variable_Goods_Count": {
"inputs": {
"name": "Goods Count",
"value": "#body('Parse_JSON')?['value']?['answers']?[iterationIndexes('Until')]?['value']"
},
"runAfter": {},
"type": "SetVariable"
}
},
"case": "goods"
},
"Case_Service": {
"actions": {
"Set_variable_Service_Count": {
"inputs": {
"name": "Service Count",
"value": "#body('Parse_JSON')?['value']?['answers']?[iterationIndexes('Until')]?['value']"
},
"runAfter": {},
"type": "SetVariable"
}
},
"case": "service"
}
},
"default": {
"actions": {}
},
"expression": "#body('Parse_JSON')?['value']?['answers']?[iterationIndexes('Until')]?['id']",
"runAfter": {},
"type": "Switch"
}
},
"expression": "#equals(variables('i'), length(body('Parse_JSON')?['value']?['answers']))",
"limit": {
"count": 10,
"timeout": "PT1H"
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "Until"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}

How to return index of array where value matches string variable?

I'm extracting a .txt into an array, line by line.
After doing that, I want to check for a match between a string variable and an element in the array(contains, does not have to be exact match), and return the index of said element.
Is there any solution to this?
I've both tried working with for-each loops and until-loops, but so far the app is iterating until it times out.
Considering this to be my .txt file
In the beginning, I'm just retrieving the text file and converting each line into an array.
Then I have Initialised 2 Variables and set Index to 0 and Status to false.
In the next step I'm using Until Connector, looping through the Array using outputs('Convert_txt_into_array')[variables('Index')] and check until the status is set to true.
So, Whether the status becomes true or false the index increments by 1 and loops through the Until connector. If the condition becomes true then the Index Variable is set to the current iteration by using iterationIndexes which gives us the current iteration and exits the Until block.
And Finally, I'm printing Index Variable in Compose connector for future usage [This step can be avoided].
RESULT - 1 :
RESULT - 2 :
Codeview of my logic app
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": "The #{variables('FindingString')} is at index : #{variables('Index')}",
"runAfter": {
"Until": [
"Succeeded"
]
},
"type": "Compose"
},
"Convert_txt_into_array": {
"inputs": "#split(body('Get_blob_content_(V2)'),'\r\n')",
"runAfter": {
"FindingString": [
"Succeeded"
]
},
"type": "Compose"
},
"FindingString": {
"inputs": {
"variables": [
{
"name": "FindingString",
"type": "string",
"value": "age-34"
}
]
},
"runAfter": {
"Get_blob_content_(V2)": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Get_blob_content_(V2)": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azureblob_1']['connectionId']"
}
},
"method": "get",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/files/#{encodeURIComponent(encodeURIComponent('JTJmY29udGFpbmVyJTJmc2FtcGxlVGV4dEZpbGUudHh0'))}/content",
"queries": {
"inferContentType": true
}
},
"metadata": {
"JTJmY29udGFpbmVyJTJmc2FtcGxlVGV4dEZpbGUudHh0": "/container/sampleTextFile.txt"
},
"runAfter": {},
"type": "ApiConnection"
},
"Index": {
"inputs": {
"variables": [
{
"name": "Index",
"type": "integer",
"value": 0
}
]
},
"runAfter": {
"Convert_txt_into_array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Status": {
"inputs": {
"variables": [
{
"name": "Status",
"type": "boolean",
"value": false
}
]
},
"runAfter": {
"Index": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Until": {
"actions": {
"Condition": {
"actions": {
"Set_Index": {
"inputs": {
"name": "Index",
"value": "#iterationIndexes('Until')"
},
"runAfter": {
"Set_Status_as_True": [
"Succeeded"
]
},
"type": "SetVariable"
},
"Set_Status_as_True": {
"inputs": {
"name": "Status",
"value": "#true"
},
"runAfter": {},
"type": "SetVariable"
}
},
"else": {
"actions": {
"Set_Status_as_False": {
"inputs": {
"name": "Status",
"value": "#false"
},
"runAfter": {},
"type": "SetVariable"
}
}
},
"expression": {
"and": [
{
"equals": [
"#outputs('Convert_txt_into_array')[variables('Index')]",
"#variables('FindingString')"
]
}
]
},
"runAfter": {},
"type": "If"
},
"Increment_variable": {
"inputs": {
"name": "Index",
"value": 1
},
"runAfter": {
"Condition": [
"Succeeded"
]
},
"type": "IncrementVariable"
}
},
"expression": "#equals(variables('Status'), true)",
"limit": {
"count": 60,
"timeout": "PT1H"
},
"runAfter": {
"Status": [
"Succeeded"
]
},
"type": "Until"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {
"$connections": {
"value": {
"azureblob_1": {
"connectionId": "/subscriptions/<Your_Subscription_Id>/resourceGroups/<Your_Resource_Group_Name>/providers/Microsoft.Web/connections/azureblob-1",
"connectionName": "azureblob-1",
"id": "/subscriptions/<Your_Subscription_Id>/providers/Microsoft.Web/locations/northcentralus/managedApis/azureblob"
}
}
}
}
}
This solution may not be for you but it's an option.
When you process your CSV data, instead of just adding line by line to the array, you could add an object that contains the index of each row (starting from 0). This is an example of what I mean ...
CSV File
This is a test 1
This is a test 2
This is a test 3
This is a test 4
Reference Array Variable (with objects)
[
{
"Index": 0,
"Text": "This is a test 1"
},
{
"Index": 1,
"Text": "This is a test 2"
},
{
"Index": 2,
"Text": "This is a test 3"
},
{
"Index": 3,
"Text": "This is a test 4"
}
]
You can then filter that array using the Filter array data operation like so ...
Left Side Expression = item()?['Text']
Right Side Expression = string(3) (I'm searching for a string of 3 but because it's a number, I need to treat it slightly differently, it's unlikely you'll have this problem)
That filter produces this result ...
... from which you can get the index of the first found item ...
This is the expression ...
if(greater(length(body('Filter_array')), 0), first(body('Filter_array'))['Index'], -1)
... and there you go ...
This is the JSON definition if you're interested.
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Filter_array": {
"inputs": {
"from": "#variables('Reference Array')",
"where": "#contains(item()?['Text'], string(3))"
},
"runAfter": {
"Initialize_Reference_Array": [
"Succeeded"
]
},
"type": "Query"
},
"Initialize_Found_Index": {
"inputs": {
"variables": [
{
"name": "Found Index",
"type": "integer",
"value": "#if(greater(length(body('Filter_array')), 0), first(body('Filter_array'))['Index'], -1)"
}
]
},
"runAfter": {
"Filter_array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Reference_Array": {
"inputs": {
"variables": [
{
"name": "Reference Array",
"type": "array",
"value": [
{
"Index": 0,
"Text": "This is a test 1"
},
{
"Index": 1,
"Text": "This is a test 2"
},
{
"Index": 2,
"Text": "This is a test 3"
},
{
"Index": 3,
"Text": "This is a test 4"
}
]
}
]
},
"runAfter": {},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"Recurrence": {
"evaluatedRecurrence": {
"frequency": "Month",
"interval": 3
},
"recurrence": {
"frequency": "Month",
"interval": 3
},
"type": "Recurrence"
}
}
},
"parameters": {}
}

Elastic - JSON Array nested in Array

I have to index a json to Elastic which look like the below format. My problem is that the key "variable" is array that contains json objects (I thought about "nested" datatype of Elastic) but some of those objects it's possible to contain nested json arrays inside them. (see variable CUSTOMERS).
POST /example_data/data {
"process_name": "TEST_PROCESS",
"process_version ": 0,
"process_id": "1111",
"activity_id": "111",
"name": "update_data",
"username": "testUser",
"datetime": "2018-01-01 10:00:00",
"variables": [{
"name": "ΒΑΝΚ",
"data_type": "STRING",
"value": "EUROBANK"
},{
"name": "CITY",
"data_type": "STRING",
"value": "LONDON"
}, {
"name": "CUSTOMERS",
"data_type": "ENTITY",
"value": [{
"variables": [{
"name": "CUSTOMER_NAME",
"data_type": "STRING",
"value": "JOHN"
}, {
"name": " CUSTOMER_CITY",
"data_type": "STRING",
"value": "LONDON"
}
]
}
]
}, {
"name": "CUSTOMERS",
"data_type": "ENTITY",
"value": [{
"variables": [{
"name": "CUSTOMER_NAME",
"data_type": "STRING",
"value": "ΑΘΗΝΑ"
}, {
"name": " CUSTOMER_CITY ",
"data_type": "STRING",
"value": "LIVERPOOL"
}, {
"name": " CUSTOMER_NUMBER",
"data_type": "STRING",
"value": "1234567890"
}
]
}
]
}
] }
When I'm trying to index it I get the following error
{ "error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Can't merge a non object mapping [variables.value] with an object mapping [variables.value]"
}
],
"type": "illegal_argument_exception",
"reason": "Can't merge a non object mapping [variables.value] with an object mapping [variables.value]" }, "status": 400 }
Mapping
{ "example_data": {
"mappings": {
"data": {
"properties": {
"activity_id": {
"type": "text"
},
"name": {
"type": "text"
},
"process_name": {
"type": "text"
},
"process_version": {
"type": "integer"
}
"process_id": {
"type": "text"
},
"datetime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"username": {
"type": "text",
"analyzer": "greek"
},
"variables": {
"type": "nested",
"properties": {
"data_type": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"value": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}}}
When I remove the variable CUSTOMERS that contains the array, then It works properly because there are only json objects.
Is there a way to handle that? Thanks in advance

Json schema for array of objects doesn't validate

I have this schema for a json response
{
"title": "Products",
"description": "schema for products",
"type": "array",
"properties": {
"id": {
"description": "id of a product",
"type": "integer"
},
"name": {
"description": "name of the product",
"type": "string"
},
"created_at": {
"description": "record created_at",
"type": "string",
"format": "date-time"
},
"updated_at": {
"description": "record updated_at",
"type": "string",
"format": "date-time"
}
},
"required": ["id", "name"]
}
and I want to match this schema with this json
[{
"id": 1,
"name": "Cricket Ball"
}, {
"id": 2,
"name": "Soccer Ball"
}, {
"id": 3,
"name": "football ball"
}, {
"id": 4,
"name": "Basketball ball"
}, {
"id": 5,
"name": "Table Tennis ball"
}, {
"id": 6,
"name": "Tennis ball"
}]
This schema matches the response but it also matches the schema in which the required field is this
"required": ["ids", "names"]
I think the schema is validated against the array and the objects in the array are not validated.
The way you have it set up now, your properties key refers to the array itself, not to each item, and is being ignored (because arrays don't have properties, they just have items). You need to use the items key to validate each item in the array, like so:
{
"title": "Products",
"description": "schema for products",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"description": "id of a product",
"type": "integer"
},
"name": {
"description": "name of the product",
"type": "string"
},
"created_at": {
"description": "record created_at",
"type": "string",
"format": "date-time"
},
"updated_at": {
"description": "record updated_at",
"type": "string",
"format": "date-time"
}
},
"required": ["id", "name"]
}
}
try map
new_array = response.map{ |k| { 'id': k['properties']['id']['description'], 'name': k['properties']['name']['description'] } }

Sorting arrays in Mongo

H have json document with array. As I can't add to beginning of array with push or addtoset I need to sort array. Example
{
"Component": [
{
"Id": "PDP-1",
"Links": {"Link": [
{
"Text": "Western Division",
"Url": "/1x7-en70ai/last-minute-holidays-western-division",
"Title": "Last minute holidays Western Division"
},
{
"Text": "Browse Regions ",
"Url": "/1x7-en6uly-10ts/last-minute-holidays-gambia/regions",
"Title": "Last minute holidays Gambia",
"Style": "BrowseForMore"
},
{
"Text": "City of Banjul",
"Url": "/1x6-en6vq7/holidays-city-of-banjul",
"Title": "City of Banjul Holidays"
},
{
"Text": "Western Division",
"Url": "/1x6-en70ai/holidays-western-division",
"Title": "Western Division Holidays"
}
]},
"Title": "Regions",
"Type": "PDP"
},
{
"Id": "PDP-2",
"Links": {"Link": [
{
"Text": "Bijilo",
"Url": "/1x7-enbmy6/last-minute-holidays-bijilo",
"Title": "Last minute holidays Bijilo"
},
{
"Text": "Browse Cities ",
"Url": "/1x7-en6uly-10tt/last-minute-holidays-gambia/cities",
"Title": "Last minute holidays Gambia",
"Style": "BrowseForMore"
},
{
"Text": "Banjul Beach",
"Url": "/1x6-enakgm/holidays-banjul-beach",
"Title": "Banjul Beach Holidays"
},
{
"Text": "Bijilo",
"Url": "/1x6-enbmy6/holidays-bijilo",
"Title": "Bijilo Holidays"
},
{
"Text": "Brufut Heights",
"Url": "/1x6-encok8/holidays-brufut-heights",
"Title": "Brufut Heights Holidays"
},
{
"Text": "Kololi",
"Url": "/1x6-enpnle/holidays-kololi",
"Title": "Kololi Holidays"
},
{
"Text": "Kotu",
"Url": "/1x6-enq067/holidays-kotu",
"Title": "Kotu Holidays"
}
]},
"Title": "Cities",
"Type": "PDP"
}
],
"Id": "118431",
"Template": {
"PageTemplate": {
"Code": "2B2",
"text": "041 - TEMP2 - COP_CONCOU_{LAST MINUTE}"
},
"Category": {
"Code": "1X7",
"Type": "Product",
"text": "Last minute holidays"
},
"GeoObject": {
"Code": "EN6ULY",
"text": "Gambia, The"
},
"GeoObjectType": {
"Code": "1A",
"text": "Political"
},
"GeoObjectSubType": {
"Code": "10TR",
"text": "Country"
}
},
"Type": "Content",
"Url": "/1x7-en6uly/last-minute-holidays-gambia",
"_id": {"$oid": "528492d4c90fa9fcd0436929"}
}
I want to sort this by Style in Links.Link 'BrowseForMore'. Any idea how to do it? I thought I could add dummy array with push which could then sort it the way I want. Any help appreciated
You appear to want to update the array and keep the sort order with your Links.Link.Style value at the front of the list. In which case use the $sort modifier with update.
db.collection.update(
{ _id: id },
{ $push: { "Links.Link: {$each: [doc], $sort { Style: -1 }}} }
)
The $each operator is required even if there is only one document, but can take many.
if you are trying to use $addToSet to maintain unique documents the official MongoDB line is that sets are considered to be unordered and hence the modifiers are not available here.

Resources