mapping through an array of object with different keys - javascript

I have following array
const myArrayOfPurchasedCars = [{
honda: {
user: 'et',
links: {
img: {
href: 'some0imghere'
},
year: 2010
},
{
camry: {
user: 'st',
links: {
img: {
href: 'some0imghere'
},
year: 2014
},
{
maxima: {
user: 'lt',
links: {
img: {
href: 'some0imghere'
},
year: 2015
},
{
optima: {
user: 'it',
links: {
img: {
href: 'some0imghere'
},
year: 2018
}
]
and I want to be able to access the user without having to say myarray[0].honda || myArray[1].camry.
Is there a way to do that with a map function?

You can use map and Object.values.
myArrayOfPurchasedCars.map(function (car) { return Object.values(car)[0].user; });

const myArrayOfPurchasedCars = [
{
honda: {
user: 'et',
links: {
img: {
href: 'some0imghere'
},
year: 2010
}
}
},
{
camry: {
user: 'st',
links: {
img: {
href: 'some0imghere'
},
year: 2014
}
}
},
{
maxima: {
user: 'lt',
links: {
img: {
href: 'some0imghere'
},
year: 2015
}
}
},
{
optima: {
user: 'it',
links: {
img: {
href: 'some0imghere'
},
year: 2018
}
}
}
];
const users = myArrayOfPurchasedCars.map(car => Object.getOwnPropertyNames(car).map(p => car[p].user)[0]);
console.log(users);

Related

How to aggregate a nested array using MongoDB?

I tried to use aggregate to find out each product's monthly sales in my order , but I ran into a problem.
Here's my data structures.
Order.model.ts
const OrderSchema: Schema = new Schema(
{
userId: {
type: String,
require: true,
},
products: [
{
product: {
_id: {
type: String,
},
title: {
type: String,
},
desc: {
type: String,
},
img: {
type: String,
},
categories: {
type: Array,
},
price: {
type: Number,
},
createdAt: {
type: String,
},
updatedAt: {
type: String,
},
size: {
type: String,
},
color: {
type: String,
},
},
quantity: {
type: Number,
default: 1,
},
},
],
quantity: {
type: Number,
},
total: {
type: Number,
},
address: {
type: String,
require: true,
},
status: {
type: String,
default: 'pending',
},
},
{ timestamps: true },
);
Order-service.ts
public async getIncome(productId?: string) {
const date = new Date();
const lastMonth = new Date(date.setMonth(date.getMonth() - 1));
const previousMonth = new Date(new Date().setMonth(lastMonth.getMonth() - 1));
//const lastYear = new Date(date.setFullYear(date.getFullYear() - 1));
const income = await this.order.aggregate([
{
$match: {
createdAt: { $gte: lastMonth },
...(productId && {
products: { $elemMatch: { product: { _id: productId } } },
}),
},
},
{
$project: {
month: { $month: '$createdAt' },
sales: '$total',
},
},
{
$group: {
_id: '$month',
total: { $sum: '$sales' },
},
},
]);
return income;
}
When I calculate whole sales without productId , it went well , I tried to use elemMatch to find productId , but it won't work , did I miss something ?
Try $unwind "products" array first, then apply $match:
const income = await this.order.aggregate([
{
$unwind: '$products'
},
{
$match: {
createdAt: { $gte: lastMonth },
product: { _id: productId },
},
},
{
$project: {
month: { $month: '$createdAt' },
sales: '$total',
},
},
{
$group: {
_id: '$month',
total: { $sum: '$sales' },
},
},
]);

mongoDB group by nested document with unknown path

i want group by value and my problem is screen_size and screen_resulation is changeable
is there is something like wildcard in nested document in mongodb ?
i have tried this but its not working
[
{
filters: {
screen_size: {
name: "حجم الشاشة",
value: "50",
},
screen_resulation: {
name: "دقة الشاشة",
value: "4k",
},
},
},
{
filters: {
screen_resulation: {
name: "دقة الشاشة",
value: "UHD",
},
screen_size: {
name: "حجم الشاشة",
value: "55",
},
},
},
{
filters: {
screen_resulation: {
name: "دقة الشاشة",
value: "4k",
},
screen_size: {
name: "حجم الشاشة",
value: "55",
},
},
},
];
{
$group : {
_id: "$filters.*.value", counter: { $sum: 1 }
}
}
You can get the desired result with the below approach as well:
[{$project: {
_id: '$_id',
filters: { $objectToArray: '$filters' }
}}, {$unwind: {
path: '$filters'
}}, {$group: {
_id: '$filters.v.value',
count: {$sum: 1}
}}]

Merge Two Javascript Objects with Multiple Matches Per Key

I have two objects which I am trying to merge. I am almost successfully worked with answer from this question (Merge two unordered objects with different keys but same value?).
The issue is that in my "transpatterns" object, I have two patterns that match "Intercom" key. However, in my output, it only takes the second one. I need it to list both under the same key.
Here is my code:
var hash = {};
var partitions = [{
'$': {
uuid: '{0F314A21-B066-B597-BCFA-6EC88CF8813B}'
},
name: ['AllPhones']
},
{
'$': {
uuid: '{4DCF3A89-ADA1-2770-4154-F6E0204D9A71}'
},
name: ['Unity_Connection']
},
{
'$': {
uuid: '{B653BC00-2D90-790C-AE0D-16C3DD2F8EDD}'
},
name: ['LAB-Tansform-Calling']
},
{
'$': {
uuid: '{148C8971-87E4-49D3-1536-69B6C95293B3}'
},
name: ['Blocked']
},
{
'$': {
uuid: '{25534E0F-F69A-FDDB-2FAD-34312BB6CEFC}'
},
name: ['LAB-PSTN-Sim-911']
},
{
'$': {
uuid: '{EC1E144B-2C8C-22CC-F1F5-423CF0343367}'
},
name: ['LAB-PSTN-Sim-Local']
},
{
'$': {
uuid: '{9C7F3223-AE2D-7605-C642-0CEAB81CD555}'
},
name: ['LAB-PSTN-Sim-LD']
},
{
'$': {
uuid: '{15AFADC3-859B-2806-B9D1-5678CE035E3D}'
},
name: ['LAB-PSTN-Sim-Intl']
},
{
'$': {
uuid: '{5DD43CF0-5FB0-A6A0-A71D-D284265F37C7}'
},
name: ['Agents']
},
{
'$': {
uuid: '{7FDE7E11-F821-2491-BB08-E6A41DAB205D}'
},
name: ['UCCX']
},
{
'$': {
uuid: '{17500618-9567-92B9-8C15-95D794094A3F}'
},
name: ['Intercom']
},
{
'$': {
uuid: '{77049844-AB06-F899-26D0-C0940E20D4D5}'
},
name: ['Netech_Managers']
},
{
'$': {
uuid: '{A9DD47E0-1C4A-AAB9-E859-E6EEDB26E6B0}'
},
name: ['Assistant_Route_Point']
}
];
var transpatterns = [{
'$': {
uuid: '{3FF82ECB-7364-41DB-176B-65D28885339F}'
},
pattern: ['9.19005554444'],
description: ['Sample Outbound Call Block'],
routePartitionName: ['Blocked']
},
{
'$': {
uuid: '{18C2C829-AFAE-DB28-A003-5F1731907D85}'
},
pattern: ['555555XXXX'],
description: ['Inbound DID Range'],
routePartitionName: ['AllPhones']
},
{
'$': {
uuid: '{465EFEF8-C405-8D30-2C97-4BF9907C92C6}'
},
pattern: ['3100'],
description: ['Intercom Xlate'],
routePartitionName: ['Intercom']
},
{
'$': {
uuid: '{C17E117C-41C7-D459-8CD1-B1D3C4EDC40D}'
},
pattern: ['3101'],
description: ['Intercom Xlate'],
routePartitionName: ['Intercom']
}
];
// TESTING NEW
// COMBINE OBJECTS - CREATE HASH
function classify(e) {
if (hash[e.name] || hash[e.routePartitionName]) {
Object.keys(e).forEach(function (c) {
hash[e.name || e.routePartitionName][c] = e[c];
});
} else {
hash[e.routePartitionName || e.name] = e;
}
}
// COMBINE OBJECTS - ADD VARS to HASH
partitions.forEach(classify);
transpatterns.forEach(classify);
// COMBINE OBJECTS - ITERATE HASH + REMOVE ANY FIELDS
var combo = Object.keys(hash).map(function (e) {
delete hash[e]['routePartitionName'];
return hash[e];
});
console.log(combo);
I was able to solve my problem. I determined that I needed to collapse the object with multiple items associated with the same key before I merged the two objects. I was able to use the answer from this question to help me do this.
How to combine JSON object with same key and add their other corresponding values?
Here is the code I came up with that seems to work nicely.
// DEFINE VARIABLES
var partitions = [{
'$': {
uuid: '{0F314A21-B066-B597-BCFA-6EC88CF8813B}'
},
name: ['AllPhones']
},
{
'$': {
uuid: '{4DCF3A89-ADA1-2770-4154-F6E0204D9A71}'
},
name: ['Unity_Connection']
},
{
'$': {
uuid: '{B653BC00-2D90-790C-AE0D-16C3DD2F8EDD}'
},
name: ['LAB-Tansform-Calling']
},
{
'$': {
uuid: '{148C8971-87E4-49D3-1536-69B6C95293B3}'
},
name: ['Blocked']
},
{
'$': {
uuid: '{25534E0F-F69A-FDDB-2FAD-34312BB6CEFC}'
},
name: ['LAB-PSTN-Sim-911']
},
{
'$': {
uuid: '{EC1E144B-2C8C-22CC-F1F5-423CF0343367}'
},
name: ['LAB-PSTN-Sim-Local']
},
{
'$': {
uuid: '{9C7F3223-AE2D-7605-C642-0CEAB81CD555}'
},
name: ['LAB-PSTN-Sim-LD']
},
{
'$': {
uuid: '{15AFADC3-859B-2806-B9D1-5678CE035E3D}'
},
name: ['LAB-PSTN-Sim-Intl']
},
{
'$': {
uuid: '{5DD43CF0-5FB0-A6A0-A71D-D284265F37C7}'
},
name: ['Agents']
},
{
'$': {
uuid: '{7FDE7E11-F821-2491-BB08-E6A41DAB205D}'
},
name: ['UCCX']
},
{
'$': {
uuid: '{17500618-9567-92B9-8C15-95D794094A3F}'
},
name: ['Intercom']
},
{
'$': {
uuid: '{77049844-AB06-F899-26D0-C0940E20D4D5}'
},
name: ['Netech_Managers']
},
{
'$': {
uuid: '{A9DD47E0-1C4A-AAB9-E859-E6EEDB26E6B0}'
},
name: ['Assistant_Route_Point']
}
];
var transpatterns = [{
'$': {
uuid: '{3FF82ECB-7364-41DB-176B-65D28885339F}'
},
pattern: ['9.19005554444'],
description: ['Sample Outbound Call Block'],
routePartitionName: ['Blocked']
},
{
'$': {
uuid: '{18C2C829-AFAE-DB28-A003-5F1731907D85}'
},
pattern: ['555555XXXX'],
description: ['Inbound DID Range'],
routePartitionName: ['AllPhones']
},
{
'$': {
uuid: '{465EFEF8-C405-8D30-2C97-4BF9907C92C6}'
},
pattern: ['3100'],
description: ['Intercom Xlate'],
routePartitionName: ['Intercom']
},
{
'$': {
uuid: '{C17E117C-41C7-D459-8CD1-B1D3C4EDC40D}'
},
pattern: ['3101'],
description: ['Intercom Xlate'],
routePartitionName: ['Intercom']
}
];
var hash = {};
// FUNCTION - COMBINE ITEMS WITHIN OBJECT - WITH SAME KEY:routePartitionName
function combine(arr) {
var combined = arr.reduce(function (result, item) {
var current = result[item.routePartitionName];
result[item.routePartitionName] = !current ? item : {
pattern: current.pattern + ',' + item.pattern,
description: item.description,
routePartitionName: item.routePartitionName
};
return result;
}, {});
return Object.keys(combined).map(function (key) {
return combined[key];
});
}
// FUNCTION - COMBINE ITEMS WITHIN OBJECT - RUN
var result = combine(transpatterns);
// FUNCTION - COMBINE OBJECTS - CREATE HASH
function classify(e) {
if (hash[e.name] || hash[e.routePartitionName]) {
Object.keys(e).forEach(function (c) {
hash[e.name || e.routePartitionName][c] = e[c];
});
} else {
hash[e.routePartitionName || e.name] = e;
}
}
// FUNCTION - COMBINE OBJECTS - ADD VARS to HASH
partitions.forEach(classify);
result.forEach(classify);
// FUNCTION - COMBINE OBJECTS - ITERATE HASH + REMOVE ANY FIELDS
var combo = Object.keys(hash).map(function (e) {
delete hash[e]['routePartitionName'];
delete hash[e]['$'];
return hash[e];
});
console.log(combo);

How can I select articles by categories in Meteor?

I'm a beginner meteor. I create a blog with many posts(article) by each categories. This is my Collection:
if (Category.find().count() === 0) {
[
{
name: 'IT',
sub_categories: [
{ name: 'Java' },
{ name: 'PHP' },
{ name: '.NET' },
{ name: 'Android/iOS' },
{ name: 'HTML/CSS' },
{ name: 'Javascript and Framworks' },
{ name: 'Ruby on Rails' },
],
},
{
name: 'ENGLISH',
sub_categories: [
{ name: 'Listening' },
{ name: 'Speaking' },
{ name: 'Writing' },
{ name: 'Reading' },
{ name: 'Topic' },
],
},
{
name: 'SoftSkill',
sub_categories: [
{ name: 'CV and CL' },
{ name: 'Presentation' },
{ name: 'Teamwork' },
],
},
{
name: 'ENTERTAINMENT',
sub_categories: [
{ name: 'Sports' },
{ name: 'Games' },
{ name: 'Music & Videos' },
{ name: 'Fashion' },
{ name: 'Talk show' },
],
},
].forEach(doc => {
Category.insert(doc);
});
}
After I save all posts by each categories, Now I want to show it throught select option
Details:
When I click on "IT" button -> app show all sub_categories. Then I choose one option (example "Java") it will show all posts have sub_categories = "Java". Can you help me to do it?
You can use navbar for your requirement.
In that navbar you can have dropdown as navbar element
Please Follow this steps if it is useful for you

AngularJS - Restheart API (MongoDB) - Parsing the JSON result

I am using RestHeart to expose CRUD operations from MongoBD. And trying to invoke the Rest API from AngularJS and get the JSON result as in below JSON string. But I am interested only in the name, age & city fields which I stored in the MongoDB.
I am not sure how to get these values.
Javascript code:-
crudApp.controller('listController', function($scope, $http, $location,
crudService) {
$http.get('http://localhost:8081/jaydb/employees').success(
function(response) {
console.log('response : ' +JSON.stringify(response));
$scope.employees = response;
});
})
JSON Result from REST API
{
_embedded: {
rh: doc: [
{
_embedded: {
},
_links: {
self: {
href: "/jaydb/employees/55c1e7c41c49a8cd78818bc7"
},
rh: coll: {
href: "/jaydb"
},
curies: [
{
href: "http://www.restheart.org/docs/v0.10/#api-doc-{rel}",
name: "rh"
}
]
},
_type: "DOCUMENT",
_id: {
$oid: "55c1e7c41c49a8cd78818bc7"
},
name: "Anupama",
city: "Trichy",
age: 25,
_etag: {
$oid: "55c1e7c41c49a8cd78818bc8"
},
_lastupdated_on: "2015-08-05T10:39:00Z",
_created_on: "2015-08-05T10:39:00Z"
},
{
_embedded: {
},
_links: {
self: {
href: "/jaydb/employees/55c1e7ae1c49a8cd78818bc5"
},
rh: coll: {
href: "/jaydb"
},
curies: [
{
href: "http://www.restheart.org/docs/v0.10/#api-doc-{rel}",
name: "rh"
}
]
},
_type: "DOCUMENT",
_id: {
$oid: "55c1e7ae1c49a8cd78818bc5"
},
name: "Sujatha",
city: "Chennai",
age: 24,
_etag: {
$oid: "55c1e7ae1c49a8cd78818bc6"
},
_lastupdated_on: "2015-08-05T10:38:38Z",
_created_on: "2015-08-05T10:38:38Z"
},
{
_embedded: {
},
_links: {
self: {
href: "/jaydb/employees/55c1e7981c49a8cd78818bc3"
},
rh: coll: {
href: "/jaydb"
},
curies: [
{
href: "http://www.restheart.org/docs/v0.10/#api-doc-{rel}",
name: "rh"
}
]
},
_type: "DOCUMENT",
_id: {
$oid: "55c1e7981c49a8cd78818bc3"
},
name: "Soniya",
city: "Ernakulam",
age: 22,
_etag: {
$oid: "55c1e7981c49a8cd78818bc4"
},
_lastupdated_on: "2015-08-05T10:38:16Z",
_created_on: "2015-08-05T10:38:16Z"
},
{
_embedded: {
},
_links: {
self: {
href: "/jaydb/employees/55c1e7711c49a8cd78818bc1"
},
rh: coll: {
href: "/jaydb"
},
curies: [
{
href: "http://www.restheart.org/docs/v0.10/#api-doc-{rel}",
name: "rh"
}
]
},
_type: "DOCUMENT",
_id: {
$oid: "55c1e7711c49a8cd78818bc1"
},
name: "Reshma",
city: "Trivandrum",
age: 21,
_etag: {
$oid: "55c1e7711c49a8cd78818bc2"
},
_lastupdated_on: "2015-08-05T10:37:37Z",
_created_on: "2015-08-05T10:37:37Z"
},
{
_embedded: {
},
_links: {
self: {
href: "/jaydb/employees/55c1d3a8b216e0710f8ee0ab"
},
rh: coll: {
href: "/jaydb"
},
curies: [
{
href: "http://www.restheart.org/docs/v0.10/#api-doc-{rel}",
name: "rh"
}
]
},
_type: "DOCUMENT",
_id: {
$oid: "55c1d3a8b216e0710f8ee0ab"
},
name: "Michael",
city: "Tokyo",
age: 23,
_created_on: "2015-08-05T09:13:12Z"
}
]
},
_links: {
},
_type: "COLLECTION",
_id: "employees",
_created_on: "2015-08-05T09:38:36Z",
_etag: {
$oid: "55c1d99c1c49a8cd78818bb6"
},
_lastupdated_on: "2015-08-05T09:38:36Z",
_collection-props-cached: false,
_returned: 5
}
Ref: http://restheart.org/docs/walkthrough.html
RESTHeart uses the HAL format, have a look at the resource representation section of the restheart documentation for more information.
In summary, your request is a GET to a collection resource: the response includes the collection's own properties at the first level and its documents as embedded resources.
You access the collection's documents via the _embedded property that includes the array rh:doc; the element of this array are the your documents.
Also note that the documents are paginated: by default RESTHeart returns the first (up to) 1000 documents. You can control the pagination via the page and pagesize query parameters.
If you also pass the count query parameter, you'll get the _size and _total_pages properties.
The _links parameter includes the next and eventually the previous links that point to the next and previous page.

Categories

Resources