let parameters = {
"lifespanCount": 3,
"parameters": {
"fields": {
"date.original": {
"stringValue": "tomorrow",
"kind": "stringValue"
},
"duration.original": {
"stringValue": "3 days",
"kind": "stringValue"
},
"date": {
"structValue": {
"fields": {
"sys.date.recent.original": {
"stringValue": "tomorrow",
"kind": "stringValue"
},
"sys.date.original": {
"stringValue": "tomorrow",
"kind": "stringValue"
},
"sys.date": {
"stringValue": "2018-12-11T12:00:00-05:00",
"kind": "stringValue"
},
"sys.date.recent": {
"stringValue": "2018-12-11T12:00:00-05:00",
"kind": "stringValue"
},
"sys.date.partial": {
"stringValue": "2018-12-11T12:00:00-05:00",
"kind": "stringValue"
},
"sys.date.partial.original": {
"stringValue": "tomorrow",
"kind": "stringValue"
}
}
},
"kind": "structValue"
},
"yes.original": {
"stringValue": "",
"kind": "stringValue"
},
"duration": {
"structValue": {
"fields": {
"sys.duration.object": {
"structValue": {
"fields": {}
},
"kind": "structValue"
},
"sys.duration": {
"structValue": {
"fields": {
"unit": {
"stringValue": "day",
"kind": "stringValue"
},
"amount": {
"numberValue": 3,
"kind": "numberValue"
}
}
},
"kind": "structValue"
},
"sys.duration.original": {
"stringValue": "3 days",
"kind": "stringValue"
}
}
},
"kind": "structValue"
},
"location.original": {
"stringValue": "china",
"kind": "stringValue"
},
"location": {
"structValue": {
"fields": {
"sys.geo-country.original": {
"stringValue": "china",
"kind": "stringValue"
},
"sys.geo-country.object": {
"structValue": {
"fields": {}
},
"kind": "structValue"
},
"sys.geo-country": {
"stringValue": "China",
"kind": "stringValue"
}
}
},
"kind": "structValue"
}
}
}
}
From above object what is the best way to get values like,
let date = parameters.fields['date'].structValue.fields['sys.date'].stringValue;
let country = parameters.fields['location'].structValue.fields['sys.geo-country'].stringValue
what can be a common function so, anyone can access value directly if pass object and key
i have tried object.values(), object.keys() have also read MDN docs but not getting much more regarding this. what my aim is to get the value from object when i pass any key with object.
Based purely on your two examples, the easiest way seems to be:
function getString(paramField, structField) {
if (parameters.fields[paramField] && parameters.fields[paramField].structValue.fields[structField]) {
return parameters.fields[paramField].structValue.fields[structField].stringValue;
}
return '';
}
Maybe some additional checks are in order, depending on the likelihood of other variance to the structure.
Then the calling code can just be:
let date = getString('date', 'sys.date');
Related
GOAL: Get the values associated with the characteristic named "ram"
Example Object/Schema:
Showcase Path: product{}.characteristics[].values[]
Product {
"characteristics": [ //1st level
{ //1st level object
"name": "ram",
"values": [ //2nd level
{"value": 2}, //to be returned in aggregation
{"value": 4} //to be returned in aggregation
]
}
]
}
Document:
{
"_index": "product",
"_type": "_doc",
"_id": "18",
"_score": 1.0,
"_source": {
"doc": {
"id": 18,
"name": "iphone_11",
"localizedName": [
{
"locale": "en-US",
"value": "iPhone 11"
}
],
"productType": null,
"shops": [
],
"characteristics": [
{
"name": "ram",
"values": [
{
"value": "2",
"localizedValues": [
]
},
{
"value": "4",
"localizedValues": [
]
}
],
"localizedName": [
{
"id": 15,
"locale": "en-US",
"value": "Ram"
}
]
}
]
}
}
}
Mappings:
{
"product": {
"mappings": {
"properties": {
"doc": {
"properties": {
"characteristics": {
"type": "nested",
"properties": {
"localizedName": {
"properties": {
"id": {
"type": "long"
},
"locale": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"value": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"values": {
"type": "nested",
"properties": {
"value": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
},
"id": {
"type": "long"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
}
Current aggregation traversal:
{
"size": 0,
"aggs": {
"characteristics": {
"nested": {
"path": "characteristics"
},
"aggs": {
"ram": {
"filter": {
"bool": {
"must": [
{
"term": {
"characteristics.name": "ram"
}
}
]
}
},
"aggs": {
"values": {
"nested": {
"path": "characteristics.values"
},
"aggs": {
"all_values": {
"terms": {
"field": "characteristics.values.value"
}
}
}
}
}
}
}
}
}
}
Response:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"aggregations": {
"characteristics": {
"meta": {},
"doc_count": 0,
"ram": {
"meta": {},
"doc_count": 0,
"values": {
"doc_count": 0,
"all_values": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
}
}
}
}
}
}
This seems to work in Elasticsearch 7.15 (based on your second sample):
{
"size": 0,
"aggs": {
"characteristics": {
"nested": {
"path": "characteristics"
},
"aggs": {
"ram": {
"filter": {
"bool": {
"must": [
{
"term": {
"characteristics.name": "ram"
}
}
]
}
},
"aggs": {
"values": {
"nested": {
"path": "characteristics.values"
},
"aggs": {
"all_values": {
"terms": {
"field": "characteristics.values.value"
}
}
}
}
}
}
}
}
}
}
It's quite convoluted though so maybe it would make sense to create an additional "attribute values" index which would have a doc for each attribute value, containing also attribute name and product id/name? Then aggregation would get way simpler.
I've got an elasticsearch cluster I'm running a search against multiple indices (msearch) which returns an array of objects (one object for each index being queried). Each of these objects has an array of hits inside of a hits object. I'm really only after the _source object. How would you go about getting an array of all the nested "_source" objects?
[
{
"hits": {
"hits": [
{
"_index": "index1",
"_type": "type1",
"_id": "1",
"_score": 12.163426,
"_source": {
"somekey": "some value",
"someotherkey": "another value"
}
}
]
},
},
{
"hits": {
"hits": []
},
},
{
"hits": {
"hits": [
{
"_index": "index2",
"_type": "type2",
"_id": "2",
"_score": 7.0380797,
"_source": {
"somekey": "some value",
"someotherkey": "another value"
}
},
{
"_index": "index2",
"_type": "type2",
"_id": "3",
"_score": 6.07253,
"_source": {
"somekey": "some value 2",
"someotherkey": "another value 2"
}
}
]
},
},
]
You may use Array.prototype.flatMap() to traverse your outer array and Array.prototype.map() to turn hits.hits into array of _source properties as items:
const src = [{"hits":{"hits":[{"_index":"index1","_type":"type1","_id":"1","_score":12.163426,"_source":{"somekey":"some value","someotherkey":"another value"}}]},},{"hits":{"hits":[]},},{"hits":{"hits":[{"_index":"index2","_type":"type2","_id":"2","_score":7.0380797,"_source":{"somekey":"some value1","someotherkey":"another value1"}},{"_index":"index2","_type":"type2","_id":"3","_score":6.07253,"_source":{"somekey":"some value 2","someotherkey":"another value 2"}}]},},],
result = src.flatMap(o => o.hits.hits.map(({_source}) => _source))
console.log(result)
.as-console-wrapper{min-height:100%;}
you can reduce the objects:
const src = [
{
"hits": {
"hits": [
{
"_index": "index1",
"_type": "type1",
"_id": "1",
"_score": 12.163426,
"_source": {
"somekey": "some value",
"someotherkey": "another value"
}
}
]
},
},
{
"hits": {
"hits": []
},
},
{
"hits": {
"hits": [
{
"_index": "index2",
"_type": "type2",
"_id": "2",
"_score": 7.0380797,
"_source": {
"somekey": "some value",
"someotherkey": "another value"
}
},
{
"_index": "index2",
"_type": "type2",
"_id": "3",
"_score": 6.07253,
"_source": {
"somekey": "some value 2",
"someotherkey": "another value 2"
}
}
]
},
},
];
console.log(src.reduce((prev, el) => [...prev, ...el.hits.hits.map(o => o['_source'])], []))
In vanilla JavaScript, how would I find unique locations from this object and make them keys, and place all items with that location as values. (can install lodash if necessary).
So this:
[
{
"item": {
"id": "cat"
},
"location": {
"id": "porch"
}
},
{
"item": {
"id": "dog"
},
"location": {
"id": "porch"
}
},
{
"item": {
"id": "snake"
},
"location": {
"id": "forest"
}
},
{
"item": {
"id": "bird"
},
"location": {
"id": "forest"
}
},
{
"item": {
"id": "beer"
},
"location": {
"id": "fridge"
}
}
]
Becomes this:
[
{
"porch": [
{
"id": "cat"
},
{
"id": "dog"
}
]
},
{
"forest": [
{
"id": "snake"
},
{
"id": "bird"
}
]
},
{
"fridge": [
{
"id": "beer"
}
]
}
]
PEN
// modified desired result
[
{
"location": {
"name": "porch",
"items": [
{
"title": "cat"
},
{
"title": "dog"
}
]
}
},
{
"location": {
"name": "forest",
"items": [
{
"title": "snake"
},
{
"title": "bird"
}
]
}
},
{
"location": {
"name": "fridge",
"items": [
{
"title": "beer"
}
]
}
}
]
let obj = [
{
"item": {
"id": "cat"
},
"location": {
"id": "porch"
}
},
{
"item": {
"id": "dog"
},
"location": {
"id": "porch"
}
},
{
"item": {
"id": "snake"
},
"location": {
"id": "forest"
}
},
{
"item": {
"id": "bird"
},
"location": {
"id": "forest"
}
},
{
"item": {
"id": "beer"
},
"location": {
"id": "fridge"
}
}
]
let result = {};
obj.forEach(({item, location}) => {
if(!result[location.id]) result[location.id] = []
result[location.id].push({title: item.id})
})
result = Object.keys(result).map(key => ({
"location": {
"name": key,
"items": result[key]
}
}))
result contains required output.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I need a help with a function that returns array with matched objects based on user input.
We enter value and search only inside this keys
1. title.label
2. ['im:artist'].label
ES6 solution highly appriciated :-)
Thanks in advance.
const fetchedData = [
{
"im:name": {
"label": "John Christmas songs"
},
"im:image": [
{
"label": "https://is3-ssl.mzstatic.com/image/thumb/Music118/v4/a9/33/a5/a933a5a8-b731-c8aa-386d-4f6f78520cca/00602517645981.rgb.jpg/55x55bb.png",
"attributes": {
"height": "55"
}
},
{
"label": "https://is5-ssl.mzstatic.com/image/thumb/Music118/v4/a9/33/a5/a933a5a8-b731-c8aa-386d-4f6f78520cca/00602517645981.rgb.jpg/60x60bb.png",
"attributes": {
"height": "60"
}
},
{
"label": "https://is4-ssl.mzstatic.com/image/thumb/Music118/v4/a9/33/a5/a933a5a8-b731-c8aa-386d-4f6f78520cca/00602517645981.rgb.jpg/170x170bb.png",
"attributes": {
"height": "170"
}
}
],
"im:itemCount": {
"label": "25"
},
"im:price": {
"label": "$8.99",
"attributes": {
"amount": "8.99000",
"currency": "USD"
}
},
"im:contentType": {
"im:contentType": {
"attributes": {
"term": "Album",
"label": "Album"
}
},
"attributes": {
"term": "Music",
"label": "Music"
}
},
"rights": {
"label": "This Compilation ℗ 2008 EMI Music North America / Sony BMG Music / UMG Recordings, Inc."
},
"title": {
"label": "The Essential NOW That's What I Call Christmas - Various Artists"
},
"link": {
"attributes": {
"rel": "alternate",
"type": "text/html",
"href": "https://music.apple.com/us/album/the-essential-now-thats-what-i-call-christmas/1440793555?uo=2"
}
},
"id": {
"label": "https://music.apple.com/us/album/the-essential-now-thats-what-i-call-christmas/1440793555?uo=2",
"attributes": {
"im:id": "1440793555"
}
},
"im:artist": {
"label": "John Christmas"
},
"category": {
"attributes": {
"im:id": "8",
"term": "Holiday",
"scheme": "https://music.apple.com/us/genre/music-holiday/id8?uo=2",
"label": "Holiday"
}
},
"im:releaseDate": {
"label": "2008-01-01T00:00:00-07:00",
"attributes": {
"label": "January 1, 2008"
}
}
},
{
"im:name": {
"label": "The Essential NOW That's What I Call Christmas"
},
"im:image": [
{
"label": "https://is3-ssl.mzstatic.com/image/thumb/Music118/v4/a9/33/a5/a933a5a8-b731-c8aa-386d-4f6f78520cca/00602517645981.rgb.jpg/55x55bb.png",
"attributes": {
"height": "55"
}
},
{
"label": "https://is5-ssl.mzstatic.com/image/thumb/Music118/v4/a9/33/a5/a933a5a8-b731-c8aa-386d-4f6f78520cca/00602517645981.rgb.jpg/60x60bb.png",
"attributes": {
"height": "60"
}
},
{
"label": "https://is4-ssl.mzstatic.com/image/thumb/Music118/v4/a9/33/a5/a933a5a8-b731-c8aa-386d-4f6f78520cca/00602517645981.rgb.jpg/170x170bb.png",
"attributes": {
"height": "170"
}
}
],
"im:itemCount": {
"label": "25"
},
"im:price": {
"label": "$8.99",
"attributes": {
"amount": "8.99000",
"currency": "USD"
}
},
"im:contentType": {
"im:contentType": {
"attributes": {
"term": "Album",
"label": "Album"
}
},
"attributes": {
"term": "Music",
"label": "Music"
}
},
"rights": {
"label": "This Compilation ℗ 2008 EMI Music North America / Sony BMG Music / UMG Recordings, Inc."
},
"title": {
"label": "The Essential NOW That's What I Call Christmas - Various Artists"
},
"link": {
"attributes": {
"rel": "alternate",
"type": "text/html",
"href": "https://music.apple.com/us/album/the-essential-now-thats-what-i-call-christmas/1440793555?uo=2"
}
},
"id": {
"label": "https://music.apple.com/us/album/the-essential-now-thats-what-i-call-christmas/1440793555?uo=2",
"attributes": {
"im:id": "1440793555"
}
},
"im:artist": {
"label": "Various Artists"
},
"category": {
"attributes": {
"im:id": "8",
"term": "Holiday",
"scheme": "https://music.apple.com/us/genre/music-holiday/id8?uo=2",
"label": "Holiday"
}
},
"im:releaseDate": {
"label": "2008-01-01T00:00:00-07:00",
"attributes": {
"label": "January 1, 2008"
}
}
},
{
"im:name": {
"label": "Christmas"
},
"im:image": [
{
"label": "https://is2-ssl.mzstatic.com/image/thumb/Music6/v4/95/da/b2/95dab2db-b597-d466-490d-58aa56b54a17/093624942788.jpg/55x55bb.png",
"attributes": {
"height": "55"
}
},
{
"label": "https://is4-ssl.mzstatic.com/image/thumb/Music6/v4/95/da/b2/95dab2db-b597-d466-490d-58aa56b54a17/093624942788.jpg/60x60bb.png",
"attributes": {
"height": "60"
}
},
{
"label": "https://is3-ssl.mzstatic.com/image/thumb/Music6/v4/95/da/b2/95dab2db-b597-d466-490d-58aa56b54a17/093624942788.jpg/170x170bb.png",
"attributes": {
"height": "170"
}
}
],
"im:itemCount": {
"label": "16"
},
"im:price": {
"label": "$6.99",
"attributes": {
"amount": "6.99000",
"currency": "USD"
}
},
"im:contentType": {
"im:contentType": {
"attributes": {
"term": "Album",
"label": "Album"
}
},
"attributes": {
"term": "Music",
"label": "Music"
}
},
"rights": {
"label": "℗ 2011 Reprise Records"
},
"title": {
"label": "Christmas - Michael Bublé"
},
"link": {
"attributes": {
"rel": "alternate",
"type": "text/html",
"href": "https://music.apple.com/us/album/christmas/669854820?uo=2"
}
},
"id": {
"label": "https://music.apple.com/us/album/christmas/669854820?uo=2",
"attributes": {
"im:id": "669854820"
}
},
"im:artist": {
"label": "Michael Bublé",
"attributes": {
"href": "https://music.apple.com/us/artist/michael-bubl%C3%A9/799597?uo=2"
}
},
"category": {
"attributes": {
"im:id": "8",
"term": "Holiday",
"scheme": "https://music.apple.com/us/genre/music-holiday/id8?uo=2",
"label": "Holiday"
}
},
"im:releaseDate": {
"label": "2011-10-14T00:00:00-07:00",
"attributes": {
"label": "October 14, 2011"
}
}
}
]
Object.filter = (obj, predicate) =>
Object.keys(obj)
.filter( key => predicate(obj[key]) )
.reduce( (res, key) => (res[key] = obj[key], res), {} );
var filtered = Object.filter(fetchedData, obj => obj['im:name'].label.includes('Christmas') || obj['im:artist'].label.includes('Christmas') );
console.log(filtered);
Link to fiddle
https://jsfiddle.net/pr8vxyhn/2/
I achieved goal, sorry, I promise I`ll be more precise in future and always submit my code.
you can try this approach, here I'm using the arrow function. You have to make http request and fetch your data then apply this filter function.
Object.filter = (obj, predicate) =>
Object.keys(obj)
.filter( key => predicate(obj[key]) )
.reduce( (res, key) => (res[key] = obj[key], res), {} );
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, score => score > 1);
console.log(filtered);
The response of "GET https://www.googleapis.com/youtube/v3/playlistItems" for a Playlist contains deleted video will return missing item in the array, Checked the errors page however nothing seems to be returning an error in such a case.
Playlistid: PLn0Hg2TufJCmcAxBFzk8z28M7bph-TV2L
Deleted Videoid: _cXqnTRHpZU
response:
/**
* API response
*/
{
"kind": "youtube#playlistItemListResponse",
"etag": "\"DuHzAJ-eQIiCIp7p4ldoVcVAOeY/T8BMpwombSYE5-LT4FpqCHDEwUQ\"",
"pageInfo": {
"totalResults": 10,
"resultsPerPage": 50
},
"items": [
{
"kind": "youtube#playlistItem",
"etag": "\"DuHzAJ-eQIiCIp7p4ldoVcVAOeY/4rqnSq9-GjuC3jGefwsyaa5CBvg\"",
"id": "UExuMEhnMlR1ZkpDbWNBeEJGems4ejI4TTdicGgtVFYyTC41MjE1MkI0OTQ2QzJGNzNG",
"contentDetails": {
"videoId": "ob6ISU-f1ho",
"videoPublishedAt": "2011-05-01T16:25:52.000Z"
}
},
{
"kind": "youtube#playlistItem",
"etag": "\"DuHzAJ-eQIiCIp7p4ldoVcVAOeY/RFwjMeMjCTaRZUDphrJCA7UUBkE\"",
"id": "UExuMEhnMlR1ZkpDbWNBeEJGems4ejI4TTdicGgtVFYyTC41MzJCQjBCNDIyRkJDN0VD",
"contentDetails": {
"videoId": "CGRf2Mpj8Yc",
"videoPublishedAt": "2009-09-27T07:59:37.000Z"
}
},
{
"kind": "youtube#playlistItem",
"etag": "\"DuHzAJ-eQIiCIp7p4ldoVcVAOeY/iUGZwVKJfLxCV-8Bo2riBnbGl_c\"",
"id": "UExuMEhnMlR1ZkpDbWNBeEJGems4ejI4TTdicGgtVFYyTC5DQUNERDQ2NkIzRUQxNTY1",
"contentDetails": {
"videoId": "hEhYol0gEg4",
"videoPublishedAt": "2014-03-28T17:44:11.000Z"
}
},
{
"kind": "youtube#playlistItem",
"etag": "\"DuHzAJ-eQIiCIp7p4ldoVcVAOeY/u_C1CEJaTi1zTsOIkXif0D5q1b8\"",
"id": "UExuMEhnMlR1ZkpDbWNBeEJGems4ejI4TTdicGgtVFYyTC45NDk1REZENzhEMzU5MDQz",
"contentDetails": {
"videoId": "wqv6r02ndLo",
"videoPublishedAt": "2013-10-02T10:23:13.000Z"
}
},
{
"kind": "youtube#playlistItem",
"etag": "\"DuHzAJ-eQIiCIp7p4ldoVcVAOeY/PMFK40fcEeXgwuNE3gdtDX4rE5M\"",
"id": "UExuMEhnMlR1ZkpDbWNBeEJGems4ejI4TTdicGgtVFYyTC5GNjNDRDREMDQxOThCMDQ2",
"contentDetails": {
"videoId": "eRr6TibE9G0",
"videoPublishedAt": "2014-05-14T11:59:06.000Z"
}
},
{
"kind": "youtube#playlistItem",
"etag": "\"DuHzAJ-eQIiCIp7p4ldoVcVAOeY/uYJMJTAtsEIisl_vothDzAtUmXc\"",
"id": "UExuMEhnMlR1ZkpDbWNBeEJGems4ejI4TTdicGgtVFYyTC40NzZCMERDMjVEN0RFRThB",
"contentDetails": {
"videoId": "JISlUIUY3sA",
"videoPublishedAt": "2013-05-07T17:57:02.000Z"
}
},
{
"kind": "youtube#playlistItem",
"etag": "\"DuHzAJ-eQIiCIp7p4ldoVcVAOeY/fnfbDo29xDX_41j7WwAHlOWCRXs\"",
"id": "UExuMEhnMlR1ZkpDbWNBeEJGems4ejI4TTdicGgtVFYyTC5EMEEwRUY5M0RDRTU3NDJC",
"contentDetails": {
"videoId": "rvXbj0jh2lA",
"videoPublishedAt": "2014-05-28T17:55:37.000Z"
}
},
{
"kind": "youtube#playlistItem",
"etag": "\"DuHzAJ-eQIiCIp7p4ldoVcVAOeY/MtvoZWwjFDcxXIlop7Nwu0hgnhI\"",
"id": "UExuMEhnMlR1ZkpDbWNBeEJGems4ejI4TTdicGgtVFYyTC45ODRDNTg0QjA4NkFBNkQy",
"contentDetails": {
"videoId": "ExEP-ZhT3sQ",
"videoPublishedAt": "2013-11-08T17:51:22.000Z"
}
},
{
"kind": "youtube#playlistItem",
"etag": "\"DuHzAJ-eQIiCIp7p4ldoVcVAOeY/VP-V_aDLbLQO7lHFj7TsZBDYj1U\"",
"id": "UExuMEhnMlR1ZkpDbWNBeEJGems4ejI4TTdicGgtVFYyTC4zMDg5MkQ5MEVDMEM1NTg2",
"contentDetails": {
"videoId": "lWkhXQJMPCQ",
"videoPublishedAt": "2013-01-21T21:28:51.000Z"
}
}
]
}
In my case the "totalResults": 10, however the array is returning 9 items. According to my testing the only way to generate the error
GET https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails%2Cstatus&maxResults=50&playlistId=PLn0Hg2TufJCmcAxBFzk8z28M7bph-TV2L&videoId=_cXqnTRHpZU&key={YOUR_API_KEY}
Response:
404
- Show headers -
{
"error": {
"errors": [
{
"domain": "youtube.playlistItem",
"reason": "videoNotFound",
"message": "Video not found.",
"locationType": "parameter",
"location": "videoId"
}
],
"code": 404,
"message": "Video not found."
}
}
The purpose behind this is to detect these deleted video in a specific playlist and then to delete it.