How to get a specific object from whole object? - javascript

I am trying to get specific object from a whole object below is the example
by using localStorage.getItem('shop/elasticCache/shirt');
I get below data
{"description":"Tech Shirt","configurable_options":[{"attribute_id":80,"values":[{"value_index":"5176","label":"RUST"}],"label":"Color","attribute_code":"color"},{"attribute_id":125,"values":[{"value_index":"2898","label":"Small"},{"value_index":"2901","label":"Medium"},{"value_index":"2904","label":"Large"}],"label":"Size","attribute_code":"size"}],"tsk":1594790209,"size_options":[2898,2901,2904],"regular_price":28,"final_price":null,"price":28,"color_options":[5176],"special_from_date":null,"id":250659,"category":[{"category_id":2,"name":"Default Category","position":1},{"category_id":3,"name":"Clothing","position":14985},{"category_id":30,"name":"Bottoms","position":798},{"category_id":58,"name":"Leggings","position":1},{"category_id":1130,"name":"Char Test Category","position":30}],"sku":"S155551","product_links":[{"link_type":"related","linked_product_sku":null,"linked_product_type":null,"position":0,"sku":"P100031"},{"link_type":"related","linked_product_sku":null,"linked_product_type":null,"position":0,"sku":"P100031"}
I am trying to get
{"category_id":3,"name":"Clothing","position":14985},{"category_id":30,"name":"Bottoms","position":798},{"category_id":58,"name":"Leggings","position":1},{"category_id":1130,"name":"Char Test Category","position":30}]
Is their any way it can be done ?

const {category} = JSON.parse(localStorage.getItem('shop/elasticCache/shirt');)
or
const {category } = {
"description": "Tech Shirt",
"configurable_options": [{
"attribute_id": 80,
"values": [{
"value_index": "5176",
"label": "RUST"
}],
"label": "Color",
"attribute_code": "color"
}, {
"attribute_id": 125,
"values": [{
"value_index": "2898",
"label": "Small"
}, {
"value_index": "2901",
"label": "Medium"
}, {
"value_index": "2904",
"label": "Large"
}],
"label": "Size",
"attribute_code": "size"
}],
"tsk": 1594790209,
"size_options": [2898, 2901, 2904],
"regular_price": 28,
"final_price": null,
"price": 28,
"color_options": [5176],
"special_from_date": null,
"id": 250659,
"category": [{
"category_id": 2,
"name": "Default Category",
"position": 1
}, {
"category_id": 3,
"name": "Clothing",
"position": 14985
}, {
"category_id": 30,
"name": "Bottoms",
"position": 798
}, {
"category_id": 58,
"name": "Leggings",
"position": 1
}, {
"category_id": 1130,
"name": "Char Test Category",
"position": 30
}],
"sku": "S155551",
"product_links": [{
"link_type": "related",
"linked_product_sku": null,
"linked_product_type": null,
"position": 0,
"sku": "P100031"
}, {
"link_type": "related",
"linked_product_sku": null,
"linked_product_type": null,
"position": 0,
"sku": "P100031"
}]
}

objc={"description":"Tech Shirt","configurable_options":
[{"attribute_id":80,"values":[{"value_index":"5176","label":"RUST"}],
"label":"Color","attribute_code":"color"},
{"attribute_id":125,"values":[{"value_index":"2898","label":"Small"}
,{"value_index":"2901","label":"Medium"},
{"value_index":"2904","label":"Large"}],
"label":"Size","attribute_code":"size"}],
"tsk":1594790209,"size_options":[2898,2901,2904]
,"regular_price":28,"final_price":null,"price":28,
"color_options":[5176],"special_from_date":null,"id":250659,
"category":[{"category_id":2,"name":"Default Category","position":1},
{"category_id":3,"name":"Clothing","position":14985},
{"category_id":30,"name":"Bottoms","position":798},
{"category_id":58,"name":"Leggings","position":1},
{"category_id":1130,"name":"Char Test Category","position":30}],
"sku":"S155551","product_links":
[{"link_type":"related","linked_product_sku":null,"linked_product_type":null,"position":0,"sku":"P100031"},
{"link_type":"related","linked_product_sku":null,"linked_product_type":null,"position":0,"sku":"P100031"}]
}
res = objc["category"]
res.shift()
console.log(res)

$(document).ready(function () {
var jsonObj = {
"description": "Tech Shirt",
"configurable_options": [{
"attribute_id": 80,
"values": [{
"value_index": "5176",
"label": "RUST"
}],
"label": "Color",
"attribute_code": "color"
}, {
"attribute_id": 125,
"values": [{
"value_index": "2898",
"label": "Small"
}, {
"value_index": "2901",
"label": "Medium"
}, {
"value_index": "2904",
"label": "Large"
}],
"label": "Size",
"attribute_code": "size"
}],
"tsk": 1594790209,
"size_options": [2898, 2901, 2904],
"regular_price": 28,
"final_price": null,
"price": 28,
"color_options": [5176],
"special_from_date": null,
"id": 250659,
"category": [{
"category_id": 2,
"name": "Default Category",
"position": 1
}, {
"category_id": 3,
"name": "Clothing",
"position": 14985
}, {
"category_id": 30,
"name": "Bottoms",
"position": 798
}, {
"category_id": 58,
"name": "Leggings",
"position": 1
}, {
"category_id": 1130,
"name": "Char Test Category",
"position": 30
}],
"sku": "S155551",
"product_links": [{
"link_type": "related",
"linked_product_sku": null,
"linked_product_type": null,
"position": 0,
"sku": "P100031"
}, {
"link_type": "related",
"linked_product_sku": null,
"linked_product_type": null,
"position": 0,
"sku": "P100031"
}]
};
for(var i = 1; i < jsonObj.category.length; i++){
console.log(jsonObj.category[i]);
}
});
You can iterate through the entire object and can get the required values. The above code gives the values of category from index 1.

Related

Checking Nesting of objects

There can two sets of objects
First can be a straight forward where is no children
const noChildObj = [{
"id": 1,
"label": ["Description"],
"lines": 1,
"type": "string",
"precision": 2,
"width": 167.8
}, {
"id": 2,
"label": ["Information", "Ratio"],
"lines": 2,
"type": "number",
"precision": 2,
"width": 167.8
}, {
"id": 3,
"label": ["Tracking", "Error"],
"lines": 2,
"type": "number",
"precision": 2,
"width": 167.8
}]
So,in this case, there is no child , so property 'width' is at the topmost layer.
Second is where nesting of objects occur
So each object in the array will have a child object
[{
"id": "257",
"label": [""],
"lines": 1,
"children": [{
"id": "Description",
"label": ["Dates"],
"lines": 1,
"type": "date",
"precision": null,
"width": 839
}]
}, {
"id": "258",
"label": ["Cumulative Return"],
"lines": 1,
"children": [{
"id": 12,
"label": ["Russell 1000 Value - Price Return"],
"lines": 1,
"type": "number",
"precision": 2,
"width": 839
}]
}]
Here each object has a child object where the property width exists
This nesting is not limited to just 1 level
It can go upto 4 levels
So my use case requires if the innermost child has width undefined or not
I do realise that through recursion , we can traverse and find out..
But is there any function which can do it in less lines of code..may be in lodash
Please help
Know only how to do with recursion:
const objArray = [{
"id": 1,
"label": ["Description"],
"lines": 1,
"type": "string",
"precision": 2,
"width": 167.8
}, {
"id": "257",
"label": [""],
"lines": 1,
"children": [{
"id": "Description",
"label": ["Dates"],
"lines": 1,
"type": "date",
"precision": null,
"width": 839
}]
}]
const getWidthDeep = (el) => el.children && el.children[0]
? getWidthDeep(el.children[0])
: el.width
const result = objArray.map(getWidthDeep)
console.log(result)

JavaScript converting tree to a nested array

I have an flowchart input using jquery flowchart library like so:
Flowchart
I get the data representation as this:
{
"operators": {
"0": {
"properties": {
"title": "Start",
"inputs": {},
"outputs": {
"outs": {
"label": "Output (:i)",
"multiple": true
}
},
"class": "start-operator"
},
"top": 0,
"left": 0
},
"1": {
"properties": {
"title": "End",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {},
"class": "end-operator"
},
"top": null,
"left": null
},
"37": {
"properties": {
"title": "CHROM",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 300,
"top": 0
},
"38": {
"properties": {
"title": "CHROM",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 580,
"top": 0
},
"39": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 920,
"top": 0
},
"40": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 300,
"top": 100
},
"41": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 300,
"top": 200
},
"42": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 620,
"top": 140
},
"43": {
"properties": {
"title": "POS",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 740,
"top": 320
}
},
"links": {
"0": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 0,
"toOperator": 37,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #e53935"
},
"1": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 1,
"toOperator": 40,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #d81b60"
},
"2": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 2,
"toOperator": 41,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #8e24aa"
},
"3": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 3,
"toOperator": 43,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #5e35b1"
},
"4": {
"fromOperator": 37,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 38,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #3949ab"
},
"5": {
"fromOperator": 40,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 42,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #546e7a"
},
"6": {
"fromOperator": 41,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 42,
"toConnector": "ins",
"toSubConnector": 1,
"color": " #039be5"
},
"7": {
"fromOperator": 38,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 39,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #00acc1"
},
"8": {
"fromOperator": 42,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 39,
"toConnector": "ins",
"toSubConnector": 1,
"color": " #00897b"
},
"9": {
"fromOperator": 39,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": "1",
"toConnector": "ins",
"toSubConnector": 0,
"color": " #43a047"
},
"10": {
"fromOperator": 43,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": "1",
"toConnector": "ins",
"toSubConnector": 1,
"color": " #7cb342"
}
},
"operatorTypes": {}
}
I want to use this for filtering data in tabulator so turn this into this:
[
{
"id": 1,
"pid": null
},
{
"id": 39,
"pid": 1
},
{
"id": 38,
"pid": 39
},
{
"id": 37,
"pid": 38
},
{
"id": 42,
"pid": 39
},
{
"id": 40,
"pid": 42
},
{
"id": 41,
"pid": 42
},
{
"id": 43,
"pid": 1
}
]
Then using this lines I turned into a tree:
const idMapping = data.reduce((acc, el, i) => {
acc[el.id] = i;
return acc;
}, {});
let root;
data.forEach(el => {
// Handle the root element
if (el.pid === null) {
root = el;
return;
}
// Use our mapping to locate the parent element in our data array
const parentEl = data[idMapping[el.pid]];
// Add our current el to its parent's `children` array
parentEl.children = [...(parentEl.children || []), el];
});
Here it is as a tree:
{
"id": 1,
"pid": null,
"children": [
{
"id": 39,
"pid": 1,
"children": [
{
"id": 38,
"pid": 39,
"children": [
{
"id": 37,
"pid": 38
}
]
},
{
"id": 42,
"pid": 39,
"children": [
{
"id": 40,
"pid": 42
},
{
"id": 41,
"pid": 42
}
]
}
]
},
{
"id": 43,
"pid": 1
}
]
}
Hovewer I want to simplify this further to just nested arrays of the id's. Like this:
[
1,
[
[
39,
[
[
38,
[
37
],
],
[
42,
[
40,
41
]
]
]
],
43
]
]
Question is, how to convert from tree to nested array?
You can use recursion to do this; leaf ids are passed upward without an array wrapper while interior node ids are wrapped in an array with a second element for their children.
const tree = { "id": 1, "pid": null, "children": [ { "id": 39, "pid": 1, "children": [ { "id": 38, "pid": 39, "children": [ { "id": 37, "pid": 38 } ] }, { "id": 42, "pid": 39, "children": [ { "id": 40, "pid": 42 }, { "id": 41, "pid": 42 } ] } ] }, { "id": 43, "pid": 1 } ] };
const objTreeToArrTree = node =>
node.children
? [node.id].concat([node.children.map(objTreeToArrTree)])
: node.id
;
console.log(JSON.stringify(objTreeToArrTree(tree), null, 2));

Declaring minimal width of serie in treemap

I have treemap chart and it has two values Squadra2 with value of 13778.00 and Squadra1 with value of 16.00
Now when treemap renders it takes percentage difference between them and split them accordingly BUT now I ended up in situation where I need to be sniper precise in order to select Squadra1 with value of 16.00
As you can see in the picture
Is there a possibility to declare for example minimal width of Squadra1, and to disallow it to go under that value ( to remain clickable ) ?
Please let me know, thank you
{
"chart": {
renderTo:"container",
"backgroundColor": "#FFFFFF"
},
"colorAxis": {
"labels": {
"enabled": false
},
"tickLength": 0,
"gridLineWidth": 0,
"min": 0,
"max": 20,
"stops": [
[
-0.001,
"#ffffff"
],
[
0.5,
"#7cb5ec"
],
[
0.501,
"#7cb5ec"
],
[
0.499,
"#ffffff"
],
[
1,
"#434348"
],
[
1.001,
"#434348"
]
]
},
"legend": {
"enabled": true,
"itemStyle": {
"color": "#FFF"
}
},
"tooltip": {},
"series": [
{
"drillUpButton": {
"position": {
"align": "center",
"verticalAlign": "bottom"
},
"theme": {
"fill": "white",
"stroke-width": 1,
"stroke": "silver",
"r": 2,
"style": {
"fontSize": "12px"
},
"states": {
"hover": {}
}
}
},
"type": "treemap",
"layoutAlgorithm": "squarified",
"allowDrillToNode": true,
"dataLabels": {
"enabled": false
},
"levelIsConstant": false,
"levels": [
{
"level": 1,
"dataLabels": {
"enabled": true
},
"borderWidth": 6,
"borderColor": "#FFFFFF"
}
],
"data": [
{
"id": "id_0",
"name": "Squadra1",
"parentName": "Squadra1"
},
{
"id": "id_0_0",
"name": "ACC",
"parent": "id_0",
"parentName": "Squadra1",
"scale": 0,
"value": 1,
"colorValue": 1.8117836848479765
},
{
"id": "id_0_1",
"name": "FEB",
"parent": "id_0",
"parentName": "Squadra1",
"scale": 0,
"value": 0,
"colorValue": 5.48633338681632
},
{
"id": "id_0_2",
"name": "MAG",
"parent": "id_0",
"parentName": "Squadra1",
"scale": 0,
"value": 8,
"colorValue": 3.4398769612396007
},
{
"id": "id_0_3",
"name": "PAM",
"parent": "id_0",
"parentName": "Squadra1",
"scale": 0,
"value": 7,
"colorValue": 2.775814171372472
},
{
"id": "id_1",
"name": "Squadra2",
"parentName": "Squadra2"
},
{
"id": "id_1_0",
"name": "ACC",
"parent": "id_1",
"parentName": "Squadra2",
"scale": 10,
"value": 13778,
"colorValue": 13.595706940649173
}
],
"events": {},
"_colorIndex": 0
}
],
"subtitle": {
"text": "",
"align": "",
"style": {
"color": "",
"fontSize": "",
"fontFamily": "",
"fontStyle": "none",
"textDecoration": "none",
"fontWeight": "none"
}
},
"title": {
"text": "",
"align": "",
"style": {
"color": "",
"fontWeight": "none",
"fontSize": "",
"fontFamily": "",
"fontStyle": "none",
"textDecoration": "none"
}
},
"lang": {
"noData": ""
},
"noData": {
"style": {
"color": "",
"fontSize": "",
"fontFamily": "",
"fontStyle": "none",
"textDecoration": "none",
"fontWeight": "none"
},
"position": {
"align": "",
"verticalAlign": "middle"
}
},
"credits": {
"enabled": false
},
"plotOptions": {
"series": {
"turboThreshold": 5000,
"colorByPoint": false
}
}
}
Link of fiddle
http://jsfiddle.net/3k5fmrut/2/
The easiest way to achieve it is to set a smaller value for Squadra2 and add an additional property with real value to point object that can be used in tooltip.formatter callback to present the real value in the tooltip. Check demo and code posted below.
Code:
data:
{
"id": "id_1",
"name": "Squadra2",
"realValue": 13778,
"parentName": "Squadra2"
}, {
"id": "id_1_0",
"name": "ACC",
"parent": "id_1",
"parentName": "Squadra2",
"scale": 10,
"value": 137.78,
"colorValue": 13.595706940649173
}
tooltip.formatter:
tooltip: {
formatter: function() {
return this.point.realValue;
}
}
Demo:
https://jsfiddle.net/BlackLabel/trz96fy7/
You can define your own algorithm to build the treemap : Highcharts treemap series
You could choose an algorithm such that each element has a minimum width and height, and the biggest elements share the remaining space.

Azure CosmosDB Query on Sub Elements

I have such documents
[
{
"id": "1",
"name": "My Product 1",
"variants": [
{
"id": 2179,
"code": "A",
"attributes": {
"att_set_1": {
"en": {
"name": "Attribute Set 1",
"data": [
{
"id": 919,
"title": "Height",
"label": "height_mm",
"v": 1200,
"unit": "mm"
},
{
"id": 921,
"title": "Weight",
"label": "weight",
"v": 500,
"unit": "kg"
},
{
"id": 923,
"title": "Other",
"label": "blah",
"v": 200,
"unit": "mm"
}
]
}
}
}
}
]
},
{
"id": "2",
"name": "My Product 2",
"variants": [
{
"id": 2180,
"code": "B",
"attributes": {
"att_set_1": {
"en": {
"name": "Attribute Set 1",
"data": [
{
"id": 919,
"title": "Height",
"label": "height_mm",
"v": 1300,
"unit": "mm"
},
{
"id": 921,
"title": "Weight",
"label": "weight",
"v": 200,
"unit": "kg"
},
{
"id": 923,
"title": "Other",
"label": "blah",
"v": 200,
"unit": "mm"
}
]
}
}
}
}
]
},
{
"id": "3",
"name": "My Product 3",
"variants": [
{
"id": 2181,
"code": "C",
"attributes": {
"att_set_1": {
"en": {
"name": "Attribute Set 1",
"data": [
{
"id": 919,
"title": "Height",
"label": "height_mm",
"v": 2000,
"unit": "mm"
},
{
"id": 921,
"title": "Weight",
"label": "weight",
"v": 999,
"unit": "kg"
},
{
"id": 923,
"title": "Other",
"label": "blah",
"v": 200,
"unit": "mm"
}
]
}
}
}
}
]
}
]
I want now to find all products where one of the variants has the Height >= 1200 and Weight >= 500
In this example this should be My Product 1 and My Product 3. My Product 2 doesn't match as the Weight Property is below the criteria.
How can I do this. Is there a way. The data structure can be changed but only if really needed.
I follow your document and created 3 sample documents as below in my cosmos db :
[
{
"id": "1",
"name": "My Product 1",
"variants": [
{
"id": 2179,
"code": "A",
"attributes": {
"att_set_1": {
"en": {
"name": "Attribute Set 1",
"data": [
{
"id": 919,
"title": "Height",
"label": "height_mm",
"v": 2330,
"unit": "mm"
},
{
"id": 921,
"title": "Weight",
"label": "weight",
"v": 2931,
"unit": "kg"
},
{
"id": 923,
"title": "Other",
"label": "blah",
"v": 200,
"unit": "mm"
}
]
}
}
}
}
]
},
{
"id": "2",
"name": "My Product 2",
"variants": [
{
"id": 2180,
"code": "B",
"attributes": {
"att_set_1": {
"en": {
"name": "Attribute Set 1",
"data": [
{
"id": 919,
"title": "Height",
"label": "height_mm",
"v": 100,
"unit": "mm"
},
{
"id": 921,
"title": "Weight",
"label": "weight",
"v": 200,
"unit": "kg"
},
{
"id": 923,
"title": "Other",
"label": "blah",
"v": 200,
"unit": "mm"
}
]
}
}
}
}
]
},
{
"id": "3",
"name": "My Product 3",
"variants": [
{
"id": 2181,
"code": "C",
"attributes": {
"att_set_1": {
"en": {
"name": "Attribute Set 1",
"data": [
{
"id": 919,
"title": "Height",
"label": "height_mm",
"v": 2000,
"unit": "mm"
},
{
"id": 921,
"title": "Weight",
"label": "weight",
"v": 999,
"unit": "kg"
},
{
"id": 923,
"title": "Other",
"label": "blah",
"v": 200,
"unit": "mm"
}
]
}
}
}
}
]
}
]
Then I use the SQL :
SELECT all FROM all join a in all.variants join b in
a.attributes.att_set_1.en.data where (b.title = 'Height' and b.v >=
2000) or (b.title = 'Weight' and b.v >= 1000)
Result data:
[
{
"all": {
"id": "1",
"name": "My Product 1",
"variants": [
{
"id": 2179,
"code": "A",
"attributes": {
"att_set_1": {
"en": {
"name": "Attribute Set 1",
"data": [
{
"id": 919,
"title": "Height",
"label": "height_mm",
"v": 2330,
"unit": "mm"
},
{
"id": 921,
"title": "Weight",
"label": "weight",
"v": 2931,
"unit": "kg"
},
{
"id": 923,
"title": "Other",
"label": "blah",
"v": 200,
"unit": "mm"
}
]
}
}
}
}
]
}
},
{
"all": {
"id": "1",
"name": "My Product 1",
"variants": [
{
"id": 2179,
"code": "A",
"attributes": {
"att_set_1": {
"en": {
"name": "Attribute Set 1",
"data": [
{
"id": 919,
"title": "Height",
"label": "height_mm",
"v": 2330,
"unit": "mm"
},
{
"id": 921,
"title": "Weight",
"label": "weight",
"v": 2931,
"unit": "kg"
},
{
"id": 923,
"title": "Other",
"label": "blah",
"v": 200,
"unit": "mm"
}
]
}
}
}
}
]
},
{
"all": {
"id": "3",
"name": "My Product 3",
"variants": [
{
"id": 2181,
"code": "C",
"attributes": {
"att_set_1": {
"en": {
"name": "Attribute Set 1",
"data": [
{
"id": 919,
"title": "Height",
"label": "height_mm",
"v": 2000,
"unit": "mm"
},
{
"id": 921,
"title": "Weight",
"label": "weight",
"v": 999,
"unit": "kg"
},
{
"id": 923,
"title": "Other",
"label": "blah",
"v": 200,
"unit": "mm"
}
]
}
}
}
}
]
}
}
]
Please notice that the value column is a keyword and cannot be used in a document. So, in my documents I remove it with v.
Update Answer:
After a few attempts, it seems impossible to directly query the results you want from the the Cosmos DB via the SQL statement.
However , Cosmos DB provides us with Stored Procedure when we face complex queries. If you do not know much about stored procedure, you can read this article.
Please refer to the stored procedure I created as below :
function sample() {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT * FROM c',
function (err, feed, options) {
if (err) throw err;
var returnArray = [];
if (!feed || !feed.length){
getContext().getResponse().setBody('no docs found');
} else{
for(var i=0;i<feed.length;i++){
var foundHeight = false, foundWeight=false;
var dataArray = feed[i].variants[0].attributes.att_set_1.en.data;
for(var j=0;j<dataArray.length;j++){
var f = dataArray[j];
if((f.title=='Height'&&f.v>=2000){
foundHeight = true;
} else if(f.title=='Weight'&&f.v>=1000)){
foundWeight = true;
}
}
if(foundHeight && foundWeight)
returnArray.push(feed[i]);
}
}
getContext().getResponse().setBody(JSON.stringify(returnArray));
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
Output result :
[
{
"id": "1",
"name": "My Product 1",
"variants": [
{
"id": 2179,
"code": "A",
"attributes": {
"att_set_1": {
"en": {
"name": "Attribute Set 1",
"data": [
{
"id": 919,
"title": "Height",
"label": "height_mm",
"v": 2330,
"unit": "mm"
},
{
"id": 921,
"title": "Weight",
"label": "weight",
"v": 2931,
"unit": "kg"
},
{
"id": 923,
"title": "Other",
"label": "blah",
"v": 200,
"unit": "mm"
}
]
}
}
}
}
]
},
{
"id": "3",
"name": "My Product 3",
"variants": [
{
"id": 2181,
"code": "C",
"attributes": {
"att_set_1": {
"en": {
"name": "Attribute Set 1",
"data": [
{
"id": 919,
"title": "Height",
"label": "height_mm",
"v": 2000,
"unit": "mm"
},
{
"id": 921,
"title": "Weight",
"label": "weight",
"v": 999,
"unit": "kg"
},
{
"id": 923,
"title": "Other",
"label": "blah",
"v": 200,
"unit": "mm"
}
]
}
}
}
}
]
}
]
This result should be what you want. You can create it on portal or in your code. Any concern ,please let me know.
Hope it helps you.

How to return a childobject from json with lodash?

Suppose I have the following json file and I would like to return the 'existing.primaryBundle.products' array preferrably with lodash:
{
"existing": {
"hasPlatinum": false,
"primaryBundle": {
"id": "2008",
"name": "TV - Entertainment, Sport",
"products": [
{
"name": "Entertainment",
"id": "100",
"price": 2600,
"gifted": false
},
{
"name": "Sport",
"id": "107",
"price": 2500,
"gifted": false,
"swappableProducts": [
{
"name": "Movies",
"id": "105",
"price": 2000,
"gifted": false
}
]
}
]
},
"extrasBundle": {
"id": "131",
"name": "Optional Extras - MUTV (Sports), LFCTV (Sports), Chelsea TV (Sports)",
"products": [
{
"name": "MUTV (Sports)",
"id": "665",
"price": 0,
"gifted": false
},
{
"name": "LFCTV (Sports)",
"id": "666",
"price": 0,
"gifted": false
},
{
"name": "Chelsea TV (Sports)",
"id": "667",
"price": 0,
"gifted": false
}
]
}
}
}
I have tried lodash and use this statement:
list2 = _.pick(existing,'primaryBundle.products')
But this returns an error and not the wanted result. How can I select this products array?
you could use _.get(nameOfObject, 'existing.primaryBundle.products') of course you would need to name your object like I've done below with sampleObject;
check out the lodash docs too
const sampleObject = {
"existing": {
"hasPlatinum": false,
"primaryBundle": {
"id": "2008",
"name": "TV - Entertainment, Sport",
"products": [{
"name": "Entertainment",
"id": "100",
"price": 2600,
"gifted": false
}, {
"name": "Sport",
"id": "107",
"price": 2500,
"gifted": false,
"swappableProducts": [{
"name": "Movies",
"id": "105",
"price": 2000,
"gifted": false
}]
}]
},
"extrasBundle": {
"id": "131",
"name": "Optional Extras - MUTV (Sports), LFCTV (Sports), Chelsea TV (Sports)",
"products": [{
"name": "MUTV (Sports)",
"id": "665",
"price": 0,
"gifted": false
}, {
"name": "LFCTV (Sports)",
"id": "666",
"price": 0,
"gifted": false
}, {
"name": "Chelsea TV (Sports)",
"id": "667",
"price": 0,
"gifted": false
}]
}
}
}
console.log(_.get(sampleObject, 'existing.primaryBundle.products'));
The main reason why it returns an error is because existing is not a global scoped object, you have to assign object to some variable like const obj = {...} and then pass the parameter to _pick method as obj.existing, yet I don't see a reason to use lodash in here, you can just reference the path to that object directly.

Categories