save mongodb coordinates array into the variable - arrays

I use a mongodb 5.0 version and I have a collection named georestaurants with a 2dsphere index
[
{ v: 2, key: { _id: 1 }, name: '_id_' },
{
v: 2,
key: { 'address.location': '2dsphere' },
name: 'add.idx',
'2dsphereIndexVersion': 3
}
]
This is one example document from my collection
db.georestaurants.findOne()
{
_id: ObjectId("61eeedc059814f22a1f6a481"),
address: {
building: '1007',
street: 'Morris Park Ave',
zipcode: '10462',
location: { type: 'Point', coordinates: [ -73.856077, 40.848447 ] }
},
borough: 'Bronx',
cuisine: 'Bakery',
grades: [
{ date: ISODate("2014-03-03T00:00:00.000Z"), grade: 'A', score: 2 },
{ date: ISODate("2013-09-11T00:00:00.000Z"), grade: 'A', score: 6 },
{
date: ISODate("2013-01-24T00:00:00.000Z"),
grade: 'A',
score: 10
},
{ date: ISODate("2011-11-23T00:00:00.000Z"), grade: 'A', score: 9 },
{
date: ISODate("2011-03-10T00:00:00.000Z"),
grade: 'B',
score: 14
}
],
name: 'Morris Park Bake Shop',
restaurant_id: '30075445'
}
I would like to get the distance between two restaurants from a query, but first of all I need to save (only) the coordinates into a variable.
My query is:
var coord=db.georestaurants.findOne({"name":/^Morris\ Park\ Bake/},{"_id":0, "address.location.coordinates":1})
coord
{
address: { location: { coordinates: [ -73.856077, 40.848447 ] } }
}
Can I save into a coord var, only longitude, latitude data[ -73.856077, 40.848447 ] or extract this info by making a query to the coord variable?
Thanks in advance!
In next statement
var coord = db.geo_restaurants.find({ "name": /^Morris\ Park\ Bake/} , {coord:"$address.situacio.coordinates", "_id":0 } )
simplifies a bit, but there are still plenty of items
coord
[ { coord: [ -73.856077, 40.848447 ] } ]
I only want into 'coord' variable
this
[ -73.856077, 40.848447 ]
thanks

Related

Mongoose | Find objects inside of an array, that each object has another array of objects to satisfy condition

I have a collection Shops. Each object in Shops collection has an array of Item objects called items.
{
_id: ObjectId(...),
shopName: 'Ice cream Shop',
items: [
<Item>{
itemName: 'Chocolate IC',
availabilities: [
{
city: 'NY',
arrivals: [
{
price: 3.99,
quantityLeft: 0,
date: 'yesterday'
},
{
price: 3.99,
quantityLeft: 40,
date: 'today'
}
]
},
{
city: 'LA',
arrivals: []
}
]
},
<Item>{
itemName: 'Strawberry IC',
availabilities: [
{
city: 'NY',
arrivals: [
{
price: 3.99,
quantityLeft: 0,
date: 'yesterday'
},
]
}
]
},
],
},
... anotherShops
I want to get list of Item objects which has overall quantityLeft more than 0 from a specific shop.
I tried this code to get all items with the name start with "Straw" from a Shop with shopName equal to 'Ice cream Shop':
const items = await Shop.aggregate()
.match({
shopName: 'Ice cream Shop',
})
.project({
items: {
$filter: {
input: "$items",
as: "item",
cond: {
$regexMatch: {
input: "$$item.itemName",
regex: `.*Straw.*`,
},
},
},
},
});
And it works. But I don't know how to sum up all quantityLeft values inside availabilities array of each item, and return only that items that has sum more than 0.
availabilities array can be an empty array [].
The city parameter also needs to be in condition. For example, only Items that are in stock in NY
I need this to get the list of items from a certain shop, and only the items that are still in stock.
Pretty hard.
I came up with this solution. If you have a better solution, please post it.
const shop = await GCShop.aggregate([
{
$match: {
shopName: 'Ice Cream Shop',
},
},
{
$unwind: "$items",
},
{
$unwind: "$items.availabilities",
},
{
$unwind: "$items.availabilities.arrivals",
},
{
$group: {
_id: "$items.id",
items_name: { $first: "$items.name" },
arrivals: {
$push: {
arrival_id: "$items.availabilities.arrivals.arrival_id",
price: "$items.availabilities.arrivals.price",
qtty: "$items.availabilities.arrivals.qtty",
},
},
totalQtty: { $sum: "$items.availabilities.arrivals.qtty" },
},
},
{
$project: {
offer_id: "$_id",
_id: 0,
offer_name: 1,
totalQtty: 1,
arrivals: 1,
},
},
{
$match: {
totalQtty: {
$gt: 0,
},
},
},
]).limit(20);

Sort and group objects alphabetically by the first letter from an array in Angular?

How can I sort and group objects alphabetically by the first letter from an array in angular? I have seen the example to do this Sort and group objects alphabetically in Javascript and the exact answer and output json i am looking in Angular.
As of now My api json is like this stackblitz
Expexted api json would like this stackblitz
I have tried this but i am unable to found the solution in angular.
real Json:
employees = [
{ name: "Abigail", age: "25" },
{ name: "Axle", age: "29" },
{ name: "Brianna", age: "25" },
{ name: "Brooklyn", age: "23" },
{ name: "Camila", age: "24" },
{ name: "Charlotte", age: "28" },
{ name: "David", age: "22" }
];
expecting json after sort and group objects alphabetically by the first letter from an array would like:
[
{
"alphabet": "A",
"record": [
{ "name": "Abigail", "age": "25" },
{ "name": "Axle", "age": "29" }
]
},
{
"alphabet": "B",
"record": [
{ "name": "Brianna", "age": "25" },
{ "name": "Brooklyn", "age": "23" }
]
},
{
"alphabet": "C",
"record": [
{ "name": "Camila", "age": "24" },
{ "name": "Charlotte", "age": "28" }
]
},
{
"alphabet": "D", "record": [
{ "name": "David", "age": "22" }
]
}
]
expected output like:
A
Abigail
Axle
B
Brianna
Brooklyn
C
Camila
Charlotte
D
David
As mentioned in the comment, there is no Typescript specific way to sort and group the data. You could the JS Array#reduce to group the objects to your requirement.
Try the following
const employees = [ { name: "Abigail", age: "25" }, { name: "Axle", age: "29" }, { name: "Brianna", age: "25" }, { name: "Brooklyn", age: "23" }, { name: "Camila", age: "24" }, { name: "Charlotte", age: "28" }, { name: "David", age: "22" } ];
const output = employees
.reduce((acc, curr) => {
const idx = acc.findIndex(e => e.alphabet === curr.name[0]);
if (idx === -1) {
acc.push({ alphabet: curr.name[0], record: [curr] });
}
else {
acc[idx].record.push(curr);
acc[idx].record.sort((r1, r2) => r1.name > r2.name ? 1 : -1);
}
return acc;
}, [])
.sort((e1, e2) => e1.alphabet > e2.alphabet ? 1 : -1);
console.log(output);
It would look like following in the Stackblitz.
export class ExpansionOverviewExample {
#ViewChild(MatAccordion, { static: false }) accordion: MatAccordion;
employees = [
{ name: "Brianna", age: "25" },
{ name: "Axle", age: "29" },
{ name: "David", age: "22" },
{ name: "Brooklyn", age: "23" },
{ name: "Camila", age: "24" },
{ name: "Abigail", age: "25" },
{ name: "Charlotte", age: "28" }
];
constructor() {
this.employees = this.employees
.reduce((acc, curr) => {
const idx = acc.findIndex(e => e.alphabet === curr.name[0]);
if (idx === -1) {
acc.push({ alphabet: curr.name[0], record: [curr] });
} else {
acc[idx].record.push(curr);
acc[idx].record.sort((r1, r2) => (r1.name > r2.name ? 1 : -1));
}
return acc;
}, [])
.sort((e1, e2) => (e1.alphabet > e2.alphabet ? 1 : -1));
}
}
You could also use safe navigation operator ?. in the template so you don't get any undefined errors before the reduce is complete.
<div *ngFor="let mani of employees">
<div>
<p>{{mani?.alphabet}}</p>
<p *ngFor="let group of mani?.record"> {{ group?.name }}</p>
<hr>
</div>
</div>
I've updated your Stackblitz

N1QL - How to add new field to each element of array which is inside another array?

I'm new at Couchbase and I got this structure:
{
items: [
{
id: "a1",
subitems: [
{
id: "b1",
name: "joe1"
},
{
id: "b2",
name: "joe2"
}
]
}
],
docType: "mydoc"
}
I need to add new field to each object inside subitems. I know how to do this with 1 level array =>
UPDATE default SET a.newField='blabla' FOR a IN items END where docType = 'mydoc';
It will produce that:
{
items: [
{
newField: "blabla",
id: "a1",
subitems: [
{
id: "b1",
name: "joe1"
},
{
id: "b2",
name: "joe2"
}
]
}
],
docType: "mydoc"
}
But I need this result:
{
items: [
{
id: "a1",
subitems: [
{
newField: "blabla",
id: "b1",
name: "joe1"
},
{
newField: "blabla",
id: "b2",
name: "joe2"
}
]
}
],
docType: "mydoc"
}
Thanks for any help.
With the upcoming Couchbase 4.5.1, you should be able to do:
UPDATE default
SET s.newField = 'newValue' FOR s IN ARRAY_FLATTEN(items[*].subitems, 1) END;
UPDATE default
SET s.newField = 'newValue' FOR s IN ARRAY_FLATTEN(ARRAY i.subitems FOR i IN items END, 1) END;
UPDATE default
SET i.subitems = ( ARRAY OBJECT_ADD(s, 'newField', 'blabla' ) FOR s IN i.subitems END ) FOR i IN items END;

Finding the highest value of object's field with specified _id in array of objects in mongodb

I am new to mongodb. I am doing simple application that uses this database. Here is my doctors collection structure:
{
_id: 1,
name: "David",
specialisation: "dentist",
description: "Super dentist",
treatments: [
{
_id: 0,
price: 2200
},
{
_id: 2,
price: 200
},
{
_id: 5,
price: 2500
},
{
_id: 8,
price: 3200
},
{
_id: 13,
price: 2050
}
],
hospitals: [1, 2, 8, 5, 20]
},
{
_id: 2,
name: "John",
specialisation: "dentist",
description: "Super dentist",
treatments: [
{
_id: 2,
price: 2500
}
],
hospitals: [1]
}
What I want to do, is to get the max value of a treatment with specified id of all doctors in collection. For example in this case if I want to check treatment with _id = 2 it should return 2500, as it is written in John's object.
Any help would be appreciated. Thanks.
Named ur collection as stack
try this
db.stack.aggregate([ {$project:{"treatments._id":1, "treatments.price":1}},
{$unwind:"$treatments"},{$match:{"treatments._id":2}},
{$sort:{"treatments.price":-1}}, {$limit:1} ]);
result: { "_id" : 2, "treatments" : { "_id" : 2, "price" : 2500 } }
ref: https://docs.mongodb.org/manual/reference/operator/aggregation/unwind/

MONGODB - adding a field in collection to a field in Item array

Suppose I have a document of the following prototype.
{
cust_id: "abc123",
ord_date: ISODate("2012-11-02T17:04:11.102Z"),
status: 'A',
price: 50,
items: [
{ sku: "xxx", qty: 25, price: 1 },
{ sku: "yyy", qty: 25, price: 1 }
]
}
My requirement is to get the total price for SKU "XXX" which is 50 * 25 (Price times quantity). How can I achieve this query's result in MONGODB?
db.YOUR_COLLECTION.aggregate({
$match: {
items.sku: "xxx"
},
$project: {
"product": {$multiply: ["$items.qty","$items.price"]},
_id: 0
}
});
I am able to achieve the solution to this by separating the query into two blocks as below.
var pipeline1 = [
{
{
"$unwind": "$items"
},
$match: {
items.sku: "xxx"
},
$project: {
"product":
{
$multiply: ["$items.qty","$items.price"]
},
_id: 0
}
}];
R = db.tb.aggregate( pipeline );

Resources