Find specific array, deep in a nested Mongo collection - javascript

I have a nested Mongo collection which looks like the following:
{
"_id": "BaiD76JR3gZFPKchn",
"ownerAdmin": "NsgdNHh84XrBJALAK",
"activities": [
{
"id": "a1",
"email": "itsarmin#gmail.com",
"type": "image",
"description": "Another one",
"createdAt": "2017-10-25T21:39:44.769Z",
"pins":
"action": "https://www.dropbox.com/as"
},
{
"id": "a2",
"email": "itsarmin#gmail.com",
"type": "image",
"description": "Comment This image For me",
"createdAt": "2017-10-25T18:42:00.484Z",
"action": "https://www.dropbox.com/s/bty2ds"
},
{
"id": "a3"
"email": "armin#four1five.com",
"type": "progress",
"description": "dasd",
"createdAt": "2017-10-24T17:28:11.748Z",
"action": 50
}
],
"createdAt": "2017-10-24T17:27:54.828Z"
}
I'm trying to query using Collection.findOne("BaiD76JR3gZFPKchn",), to return an object in "activities" using 2 field "id:a2" AND "type:image", so I end up with :
{
"id": "a2",
"email": "itsarmin#gmail.com",
"type": "image",
"description": "Comment This image For me",
"createdAt": "2017-10-25T18:42:00.484Z",
"action": "https://www.dropbox.com/s/bty2ds"
}

Try adding projection into your query.
db.collection.findOne( { _id: "BaiD76JR3gZFPKchn" },
{ activities: { $elemMatch: { id: "a2",type:"image"} }, _id: 0 })

Related

Filtering a nested array with scan in dynamodb

I trying to work out the DynamoDB scan with the nested array. I trying to get the user details base on the survey id in the nested array, My table value is like this.
{
"id": "28009dd8-5802-20f5-c7c9-af53e710ac91",
"user": {
"address1": "1, Park avenue",
"address2": "Austin",
"birthDate": "1999-01-01",
"city": "Austin",
"contact": "9876543210",
"country": "1",
"email": "rajmohan#gm.com",
"emgContact": "2",
"empStatus": "1",
"ethnicity": "5",
"firstName": "Rajmohan",
"gender": "male",
"highLevelEduc": "2",
"image": "",
"lName": "V",
"mName": "",
"nationality": "1",
"relationalStatus": "1",
"state": "43",
"telephone": "9876543210",
"zipCode": "70031"
},
"survey": [
{
"id": "e8de014a-22c1-12bf-4653-577c8031138",
"email": "rajmohan#gm.com",
"method": [
"email"
],
"name": "Rajmohan",
"onDemand": "yes",
"pollSchedule": "None",
"pollTarget": "Educator",
"telephone": "963696369",
"user_id": "413ca05f-ed91-50e7-1974-3e0280ca4a3d"
},
{
"id": "5f4db059-c8a3-e673-iygk-d857425e1077",
"created_at": 1674459043374,
"email": "test#gmail.com",
"method": [
"email"
],
"name": "New testing",
"onDemand": "yes",
"pollSchedule": "None",
"pollTarget": "Educator",
"telephone": "963696369",
"user_id": "413ca05f-ed91-50e7-2635-3e0280ca4a3d"
}
],
"summary": "test",
"user": "413ca05f-ed91-8k8y-2635-3e0280ca4a3d"
}
and my scan syntax is like that.
var param = {
TableName: 'user',
FilterExpression: 'contains(#survey.#id,:id)',
ExpressionAttributeNames: {
'#survey': 'survey',
'#id':'id'
},
ExpressionAttributeValues: {
':id': id
},
}
But I can't get the value. My point is based on the survey id I need to get the value of the user.
You cannot do what you're attempting, you would need to pass in the full value of the map which would be quite difficult to do i'm sure.
Using a list of maps
You need to know the entire map value when using contains function, as you are asking if the map is contained in the list, not if a string is contained in the map:
var mymap = {
"id": "e8de014a-22c1-12bf-4653-577c8031138",
"email": "rajmohan#gm.com",
"method": [
"email"
],
"name": "Rajmohan",
"onDemand": "yes",
"pollSchedule": "None",
"pollTarget": "Educator",
"telephone": "963696369",
"user_id": "413ca05f-ed91-50e7-1974-3e0280ca4a3d"
}
var param = {
TableName: 'user',
FilterExpression: 'contains(#survey,:mymap)',
ExpressionAttributeNames: {
'#survey': 'survey'
},
ExpressionAttributeValues: {
':mymap': mymap
},
}
Using nested maps
You should structure your list as a map:
"survey": {
"e8de014a-22c1-12bf-4653-577c8031138":{
"email": "rajmohan#gm.com",
"method": [
"email"
],
"name": "Rajmohan",
"onDemand": "yes",
"pollSchedule": "None",
"pollTarget": "Educator",
"telephone": "963696369",
"user_id": "413ca05f-ed91-50e7-1974-3e0280ca4a3d"
},
"5f4db059-c8a3-e673-iygk-d857425e1077": {
"created_at": 1674459043374,
"email": "test#gmail.com",
"method": [
"email"
],
"name": "New testing",
"onDemand": "yes",
"pollSchedule": "None",
"pollTarget": "Educator",
"telephone": "963696369",
"user_id": "413ca05f-ed91-50e7-2635-3e0280ca4a3d"
}
}
var id = "5f4db059-c8a3-e673-iygk-d857425e1077"
var param = {
TableName: 'user',
FilterExpression: 'attribute_exists(#survey.#id)',
ExpressionAttributeNames: {
'#survey': 'survey',
'#id': id
}
}

Adding attributes to existing json payload using javascript

I am getting json response as below. I want to add "**
schemas":[
"urn:ietf:params:scim:schemas:core:2.0:User", "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
],
"id":"xyz",
**
to each resource how to do this using javascript. Can anyone help.
{
"Resources": [
{
"emails": {
"type": "bobsmith01#company.com",
"value": "Personal"
},
"name": {
"familyName": "Bob-update3",
"givenName": "Smith"
},
"detail": "SUCCESS",
"userName": "bobsmith01#company.com",
"status": "200"
},
{
"emails": {
"type": "samgomes#company.com",
"value": "Personal"
},
"name": {
"familyName": "gomes",
"givenName": "sam"
},
"detail": "SUCCESS",
"userName": "samgomes#company.com",
"status": "200"
}
]
}
Required output is as below.
{
"Resources": [
{
"schemas":[
"urn:ietf:params:scim:schemas:core:2.0:User",
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
],
"id":"xyz",
"emails": {
"type": "bobsmith01#company.com",
"value": "Personal"
},
"name": {
"familyName": "Bob-update3",
"givenName": "Smith"
},
"detail": "SUCCESS",
"userName": "bobsmith01#company.com",
"status": "200"
}
{
"schemas":[
"urn:ietf:params:scim:schemas:core:2.0:User",
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
],
"id":"abc",
"emails": {
"type": "samgomes#company.com",
"value": "Personal"
},
"name": {
"familyName": "gomes",
"givenName": "sam"
},
"detail": "SUCCESS",
"userName": "samgomes#company.com",
"status": "200"
}
]
}
You can use ES6 JS spread operator (...) and Array.map to achieve this:
const orgObject = {
"Resources": [{
"emails": {
"type": "bobsmith01#company.com",
"value": "Personal"
},
"name": {
"familyName": "Bob-update3",
"givenName": "Smith"
},
"detail": "SUCCESS",
"userName": "bobsmith01#company.com",
"status": "200"
},
{
"emails": {
"type": "samgomes#company.com",
"value": "Personal"
},
"name": {
"familyName": "gomes",
"givenName": "sam"
},
"detail": "SUCCESS",
"userName": "samgomes#company.com",
"status": "200"
}
]
}
const copiedObject = {...orgObject}; // Copy object to avoid mutation preferably use lodash.cloneDeep
// loop through the object.Resources using map
copiedObject.Resources = copiedObject.Resources.map(res => {
return {
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User",
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
],
"id": "xyz",
...res // Use spread operator to copy the existing object properties from Resources
}
});
console.log(copiedObject)
.as-console-wrapper{
top:0;
max-height:100% !important;
}

Normalising JSON data

{
"id": "123",
"author": {
"id": "1",
"name": "Paul"
},
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
}
This is JSON for an article
{
result: "123",
entities: {
"articles": {
"123": {
id: "123",
author: "1",
title: "My awesome blog post",
comments: [ "324" ]
}
},
"users": {
"1": { "id": "1", "name": "Paul" },
"2": { "id": "2", "name": "Nicole" }
},
"comments": {
"324": { id: "324", "commenter": "2" }
}
}
}
Im currently looking through redux tutorials, they give a helper which normalise JSON data, does anyone know what type of normalisation this is?

JSON Object Transformation into specific Javascript Array or JSON Object

So I have this JSON Object. Let's call it var dataFetched
var dataFetched = {
"status": "ok",
"count": 4,
"count_total": 4,
"pages": 1,
"posts": [
{
"id": 57,
"type": "keyword",
"slug": "crime-scene-investigation-csi",
"url": "http://keyjargon.com/keyword/crime-scene-investigation-csi/",
"status": "publish",
"title": "Crime Scene Investigation (CSI)",
"title_plain": "Crime Scene Investigation (CSI)",
"content": "",
"excerpt": "",
"date": "2015-11-07 05:01:51",
"modified": "2015-11-07 05:01:51",
"categories": [
{
"id": 8,
"slug": "law",
"title": "Law",
"description": "",
"parent": 0,
"post_count": 1
}
],
"tags": [
],
"author": {
"id": 1,
"slug": "admin",
"name": "admin",
"first_name": "",
"last_name": "",
"nickname": "admin",
"url": "",
"description": ""
},
"comments": [
],
"attachments": [
],
"comment_count": 0,
"comment_status": "closed",
"custom_fields": {
}
},
{
"id": 50,
"type": "keyword",
"slug": "fx",
"url": "http://keyjargon.com/keyword/fx/",
"status": "publish",
"title": "FX",
"title_plain": "FX",
"content": "",
"excerpt": "",
"date": "2015-11-05 10:07:17",
"modified": "2015-11-05 10:22:10",
"categories": [
{
"id": 3,
"slug": "business",
"title": "Business",
"description": "",
"parent": 0,
"post_count": 2
}
],
"tags": [
],
"author": {
"id": 1,
"slug": "admin",
"name": "admin",
"first_name": "",
"last_name": "",
"nickname": "admin",
"url": "",
"description": ""
},
"comments": [
],
"attachments": [
],
"comment_count": 0,
"comment_status": "closed",
"custom_fields": {
}
},
{
"id": 48,
"type": "keyword",
"slug": "common-core",
"url": "http://keyjargon.com/keyword/common-core/",
"status": "publish",
"title": "Common CORE",
"title_plain": "Common CORE",
"content": "",
"excerpt": "",
"date": "2015-11-05 10:06:40",
"modified": "2015-11-07 04:58:06",
"categories": [
{
"id": 2,
"slug": "technology",
"title": "Technology",
"description": "",
"parent": 0,
"post_count": 3
}
],
"tags": [
],
"author": {
"id": 1,
"slug": "admin",
"name": "admin",
"first_name": "",
"last_name": "",
"nickname": "admin",
"url": "",
"description": ""
},
"comments": [
],
"attachments": [
],
"comment_count": 0,
"comment_status": "closed",
"custom_fields": {
}
},
{
"id": 46,
"type": "keyword",
"slug": "api",
"url": "http://keyjargon.com/keyword/api/",
"status": "publish",
"title": "API",
"title_plain": "API",
"content": "",
"excerpt": "",
"date": "2015-11-05 10:06:19",
"modified": "2015-11-05 10:21:47",
"categories": [
{
"id": 2,
"slug": "technology",
"title": "Technology",
"description": "",
"parent": 0,
"post_count": 3
}
],
"tags": [
],
"author": {
"id": 1,
"slug": "admin",
"name": "admin",
"first_name": "",
"last_name": "",
"nickname": "admin",
"url": "",
"description": ""
},
"comments": [
],
"attachments": [
],
"comment_count": 0,
"comment_status": "closed",
"custom_fields": {
}
}
]
}
I want to rearrange this result to link the Category title :
dataFetched.posts[i].categories[0].title
to the Post title :
dataFetched.post[i].title
so that each category displays all the posts titles related to it. I want my object (whether multi-demmensional array or another object) to be able to retrieve all the Posts titles related to the category.
Maybe something like this :
[Category1: {Post_titleA, PostTitleB, PostTitleC}, Category2: {PostTileF, PostTileX}, etc ] where each category can retrieve all its posts.( The format does not matter as long the Object with Category title X can retrieve all posts titles that belong to it ).
How do I do this in Javascript ? The result variable is not static but its format is the same as the one posted here.
This is what I tried so far.
// Function to sort unique values of an array
function sort_unique(arr) {
arr = arr.sort(function (a, b) { return a*1 - b*1; });
var ret = [arr[0]];
for (var i = 1; i < arr.length; i++) { // start loop at 1 as element 0 can never be a duplicate
if (arr[i-1] !== arr[i]) {
ret.push(arr[i]);
}
}
return ret;
}
//Define two arrays to be used for categories and Keywords
var keywords = [];
var industries = [];
//Fill up the categories(Industries) array and the keywords one
for ( var i = 0, iLen = dataFetched.count; i < iLen; i++) {
keywords[i] = dataFetched.posts[i].title;
industries[i] = dataFetched.posts[i].categories[0].title;
}
// Sort and eliminate duplication of category and keyword names
keywords = sort_unique(keywords);
industries = sort_unique(industries);
// Now time for trouble: Define a multi-dimmensional array that links each category/industry to its keywords **This is where I AM STUCK**
ind = new Array;
for(i=0; i<industries.length;i++){
ind[i] = new Array;
}
for(i=0;i<dataFetched.count;i++){
ind[i][0]= dataFetched.posts[i].categories[0].title;
for(j=0;j<dataFetched.count;j++){
var count = ind[i].length;
if(ind[i][0] == dataFetched.posts[j].categories[0].title){
ind[i][count] = dataFetched.posts[j].title;
}
}
}
It is possible to create object with categories. As a result all entries can be accessed by category name and you do not need to sort them to have unique titles:
var posts = dataFetched.posts;
var cat = {};
posts.forEach(
function(p) {
p.categories.forEach(
function(c) {
if (!cat[c.title])
cat[c.title] = [];
cat[c.title].push(p.title);
});
});
console.log(cat);
Output for your example:
Object {Law: Array[1], Business: Array[1], Technology: Array[2]}
Each category title is a key in this object and the arrays of posts are values of those keys.
The output example you showed is wrong, in JS there's no object like
[Category1: {Post_titleA, PostTitleB, PostTitleC}, Category2: {PostTileF, PostTileX}, etc ]
The most similar thing you can get is a JSON object like this:
{
"Category1" : ["Post_titleA", "PostTitleB", "PostTitleC"],
"Category2" : ["PostTileF", "PostTileX"],
//etc..
}
In order to achieve this, you can use the following function:
function getTitlesByCategory (json) {
var result = {}
json.posts.map(function (post) {
post.categories.map(function (category) {
result[category.title] = result[category.title] || [];
result[category.title].push(post.title);
});
});
return result;
}

Sort nested array by properties [duplicate]

This question already has answers here:
Sort array of objects by string property value
(57 answers)
Closed 8 years ago.
I have this array and I was wondering if I could sort it with the properties comments.count and likes.count separately.
For example I could just have a function to call using likes.count parameter or comments.count parameter.
{
"attribution": null,
"tags": [
],
"type": "",
"location": null,
"comments": {
"count": 2,
"data": [
{
"created_time": "1385670850",
"text": "Holy shit",
"from": {
"username": "someone",
"profile_picture": "http://url.com/profiles/profile_191120775_75sq_1365830292.jpg",
"id": "191120775"
},
"id": "599372997379438683"
},
{
"created_time": "1385680581",
"text": "",
"from": {
"username": "someone",
"profile_picture": "http://url.com/profiles/profile_1523167_75sq_1389544912.jpg",
"id": "1523167"
},
"id": "599454624038205610"
}
]
},
"likes": {
"count": 6,
"data": [
{
"username": "someone",
"profile_picture": "http://url.com/profiles/profile_2169761_75sq_1389075971.jpg",
"id": "2169761"
},
{
"username": "rashmityagi",
"profile_picture": "http://url.com/profiles/profile_393770264_75sq_1388911033.jpg",
"id": "393770264"
},
{
"username": "tylerferweda",
"profile_picture": "http://url.com/profiles/profile_191120775_75sq_1365830292.jpg",
"id": "191120775"
},
{
"username": "cbolts",
"profile_picture": "http://url.com/profiles/profile_1523167_75sq_1389544912.jpg",
"id": "1523167"
}
]
}
},
{
"attribution": null,
"tags": [
],
"type": "",
"location": null,
"comments": {
"count": 10,
"data": [
{
"created_time": "1385670850",
"text": "Holy shit",
"from": {
"username": "someone",
"profile_picture": "http://url.com/profiles/profile_191120775_75sq_1365830292.jpg",
"id": "191120775"
},
"id": "599372997379438683"
},
{
"created_time": "1385680581",
"text": "",
"from": {
"username": "someone",
"profile_picture": "http://url.com/profiles/profile_1523167_75sq_1389544912.jpg",
"id": "1523167"
},
"id": "599454624038205610"
}
]
},
"likes": {
"count": 20,
"data": [
{
"username": "someone",
"profile_picture": "http://url.com/profiles/profile_2169761_75sq_1389075971.jpg",
"id": "2169761"
},
{
"username": "rashmityagi",
"profile_picture": "http://url.com/profiles/profile_393770264_75sq_1388911033.jpg",
"id": "393770264"
},
{
"username": "tylerferweda",
"profile_picture": "http://url.com/profiles/profile_191120775_75sq_1365830292.jpg",
"id": "191120775"
},
{
"username": "cbolts",
"profile_picture": "http://url.com/profiles/profile_1523167_75sq_1389544912.jpg",
"id": "1523167"
}
]
}
},
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
json_array.sort(function(a, b) {
if(a.comments.count < b.comments.count) {
return -1;
}
if(a.comments.count > b.comments.count) {
return 1;
}
return 0;
});
You can also modify it for likes.count
Underscore.js provides great utility functions for working with arrays and objects. For your case you could use _.sortBy(...) See http://underscorejs.org/#sortBy for more details. For simple object properties it is enough to specify the object property name als last parameter.

Categories