Update Elements in Array - mongodb

Lets say I have this Object:
{town_id: 13, houses_data: [
{house_id: 5, price: 32, description: "thats a house"},
{house_id: 2, price: 12, description: "thats a house"}
]
}
And I want to update the desription of house with id 5 to "sold":
{town_id: 13, houses_data: [
{house_id: 5, price: 32, description: "sold"},
{house_id: 2, price: 12, description: "thats a house"}
]
}
What I tried:
town1 = town.findOne({town_id: 13});
Get the houses_data:
twon1.houses_data
And tried to update only the house_data where id = 5
twon1.houses_data.find({house_id: 5}).update(description: "sold");
But I get this error message:
[object Object],[object Object] has no method 'find'
What do I wrong? Thanks

You might use $ to update the first embedded document matching the given query:
db.test.town.update({town_id: 13, "houses_data.house_id":5},
{$set: { "houses_data.$.description": "sold"}})

Related

How can I sort data by the value of a flutter map? [duplicate]

This question already has answers here:
How to sort a Map by its value in dart?
(3 answers)
Closed 2 months ago.
i'm trying to sort the values i get from my realtime database converted to Map. This is what I get:
{Table 2:
{
order 1:
{
WATER: {price: 1.50, quantity: 2},
date: 2022-12-14 17:34:51.428972}
},
Table 1:
{
order 2:
{
date: 2022-12-14 17:35:04.761532,
COCA COLA: {price: 2, quantity: 1}
},
order 1:
{
DAISY: {price: 7, quantity: 1},
date: 2022-12-14 17:22:12.678864,
4 CHEESES: {price: 7, quantity: 1},
WATER: {price: 1.50, quantity: 2}
}
}
}
What I want is to compare all orders by date so as to get them chronologically, resulting in something like this:
{Table 1:
{
order 1:
{
DAISY: {price: 7, quantity: 1},
dates: 2022-12-14 17:22:12.678864,
4 CHEESES: {price: 7, quantity: 1},
WATER: {price: 1.50, quantity: 2}
},
Table 2:
{
order 1:
{
WATER: {price: 1.50, quantity: 2},
date: 2022-12-14 17:34:51.428972}
},
Table 1:
{
order 2:
{
dates: 2022-12-14 17:35:04.761532,
COCA COLA: {price: 2, quantity: 1}
},
},
}
you could easily sort any list based on date using this way
newData.sort((a, b) {
return (a['date'] as DateTime).compareTo(b['date'] as DateTime);
});
but your data is map not list and map does not have a sort or order at all ,
you should change your data structure first into array then sort it
somethings like this should work
final tables = <String, Map<String, Map>>{}; // ...your data here
final newData = tables.entries
.map(
(table) => table.value.entries.map(
(order) => {"table": table.key, "order": order.key, ...order.value},
),
)
.expand(
(element) => element,
)
.toList();
newData.sort((a, b) {
return (a['date'] as DateTime).compareTo(b['date'] as DateTime);
});

Recursion function logic friend of friend in a Graph

Hi I have this json file with these partial data, and I will be user 1 in this example, and need to create a graph vertex and connect it to my user for all my friends and then create a vertex and connect my friend friends and so on.
[
{
"id": 1,
"name": "Me",
"friends": [25, 24, 16, 8, 13, 12, 7, 15]
},
{
"id": 2,
"name": "Anne Emerson",
"friends": [3, 21, 4, 20, 24, 5, 7, 12, 18]
},
{
"id": 3,
"name": "Ashley Hopper",
"friends": [2, 22, 10, 20, 25, 11]
},
{
"id": 4,
"name": "Alba Gates",
"friends": [2, 17, 21, 11, 7, 13]
},
{
"id": 5,
"name": "Louise Pennington",
"friends": [2, 23, 22, 15, 20, 24]
},
{
"id": 6,
"name": "Shields Gilliam",
"friends": [26]
},
{
"id": 7,
"name": "Freida Evans",
"friends": [1, 4, 2, 9, 18, 17]
},
{
"id": 8,
"name": "Noel Serrano",
"friends": [1, 24, 18, 9, 16, 11, 23]
}
]
I tried to write a recursion function that goes throw my field list which are users with these ID's [3, 21, 4, 20, 24, 5, 7, 12, 18] like in the example. and create a graph vertex for the User I'm at and connect it with its parent user. and keeps going throw all my friends first then goes throw my friend friends and so on until I discovered all of the friends related to my user weather its directly or indirectly.
Graph methods to use:
create a parent vertex (ME):
let me = graph.createVertex(data: "Me")
connect vertexes together:
graph.add(.undirected, from: me, to: user25, weight: 1)
User model:
struct User: Codable, Identifiable, Hashable {
enum CodingKeys: CodingKey {
case id
case name
case friends
}
var id: Int
var name: String
var friends: [Int]
}
what I tried so far using nested loops:
for (index, i) in friends.enumerated() {
print("i: \(i)")
let getUserByID = datas.users.filter{ $0.id == index}
for (index, i) in getUserByID.enumerated() {
print(i.friends)
}
}
where friends is let friends = [25, 24, 16, 8, 13, 12, 7, 15]
The logic isn't hitting me yet and I wasn't able to achieve this in Swift 5 can anyone help ?
Sample OutPut for my friends mutual list:
John Doe - edge distance: 2, Mutual friends: 5
Bob Kemp - edge Distance: 2, Mutual friends: 3
Bryce Holmes - edge Distance: 3
James Smith - edge Distance: 3
The list should be ranked firstly by edge distance and secondly
by number of mutual friends.

How to loop through mongodb subdocument array find the matching elements and update the element fields with new values at once

For example, if a purchase order has line items like this:
and user from the client side send us line items to be updated in an array called lineItemsToUpdate and has a format like this:
[
{ unitCost: 342,
totalQuantity: 13,
acceptedQuantity: 6,
rejectedQuantity: 18,
title: 'Unbranded Concrete Pizza',
description: 'Soft',
variant: 5f2d5eb0195026e6dd549ef0 },
{ unitCost: 189,
totalQuantity: 95,
acceptedQuantity: 49,
rejectedQuantity: 16,
title: 'Handcrafted Rubber Cheese',
description: 'Assurance',
variant: 5f2d5eaf195026e6dd549b7d },
{ unitCost: 267,
totalQuantity: 18,
acceptedQuantity: 93,
rejectedQuantity: 11,
title: 'Incredible Soft Car',
description: 'solution-oriented',
variant: 5f2d5eb0195026e6dd549d3d },
]
here in the lineItemsToUpdate array, it's possible that the value of each element has been changed by the client and I want to update all the matching element by variant field in my sub-document if I describe it in the format of a user story:
update all lineItems "fields" according to lineItemsToUpdate array where the lineItemsToUpdate.[elem].variant === linitem.[elem].variant using $set, if possible $each and arrayFilters operators
I read some example through the mongodb documentation like this one:
db.students2.update(
{ },
{ $set: { "grades.$[elem].mean" : 100 } },
{
multi: true,
arrayFilters: [ { "elem.grade": { $gte: 85 } } ]
}
)
but the problem in here { $set: { "grades.$[elem].mean" : 100 } } is that the 100 value is constant and I want this part dynamic as I described in above.
Following is JS function you have to take help of.
function(c1,arr2){
var arr1 = c1.next().lineItems;
for(i=0;i<arr1.length;i++){
for(j=0;j<arr2.length;j++){
if(arr1[i].variant===arr2[j].variant){
db.purchaseOrder.update(
{ },
{ $set: { "lineItems.$[elem].unitCost" : arr2[j].unitCost,"lineItems.$[elem].totalQuantity" : arr2[j].totalQuantity } .....},
{ multi: true,
arrayFilters: [ { "elem.variant": { $eq: arr2[j].variant } } ]
}
)
}
}
}
}
Explanation
We have to pass 2 parameters: i) Mongo cursor and ii) An array.
Cursor is the collection to be updated. For your case, it is
Purchase Order. Array is lineItemsToUpdate array here.
Next we take 2 for loops to match variant field between cursor and
array.
If there is a match, we update the Purchase Order using update
command and $set operator.
Execution
Go to your Mongo Shell. Ensure the current database has Purchase
Order collection.
Define modifyItems function as below.
var modifyItems=function(c1,arr2){
var arr1 = c1.next().lineItems;
for(i=0;i<arr1.length;i++){
for(j=0;j<arr2.length;j++){
if(arr1[i].variant===arr2[j].variant){
db.purchaseOrder.update(
{ },
{ $set: { "lineItems.$[elem].unitCost" : arr2[j].unitCost,"lineItems.$[elem].totalQuantity" : arr2[j].totalQuantity }... },
{ multi: true,
arrayFilters: [ { "elem.variant": { $eq: arr2[j].variant } } ]
}
)
}
}
}
}
Define a variable arr which contains lineItemsToUpdate.
var arr=[
{ unitCost: 342,
totalQuantity: 13,
acceptedQuantity: 6,
rejectedQuantity: 18,
title: 'Unbranded Concrete Pizza',
description: 'Soft',
variant: 5f2d5eb0195026e6dd549ef0 },
{ unitCost: 189,
totalQuantity: 95,
acceptedQuantity: 49,
rejectedQuantity: 16,
title: 'Handcrafted Rubber Cheese',
description: 'Assurance',
variant: 5f2d5eaf195026e6dd549b7d },
{ unitCost: 267,
totalQuantity: 18,
acceptedQuantity: 93,
rejectedQuantity: 11,
title: 'Incredible Soft Car',
description: 'solution-oriented',
variant: 5f2d5eb0195026e6dd549d3d }
]
Now execute the JS function.
modifyItems(db.purchaseOrder.find({},{"lineItems":1,"_id":0}),arr);
If there is no error, your Purchase Order line items will be now updated with the array values in one single shot.

Using $pull with Deployd method

I have a Deployd API which exposes a json structure like this:
[
{id: "1"
username: "john",
password: " ..... ",
email: "example#gmail.com",
coins: 60,
badges: [ ],
courses:[
{ id: "123456",
title: "Animals",
grades_per_module: [ [30], [28, 26], [25, 24]]
.....
},
{ id: "112233",
title: "Food",
grades_per_module: [ [20, 25, 27], [22]]
.....
}
]
},
{id: "2"
username: "mark",
password: " ..... ",
email: "ex#gmail.com",
coins: 40,
badges: [ ],
courses:[
{ id: "123456",
title: "Animals",
grades_per_module: [ [27], [21, 30], [30, 30]]
.....
}
]
}
]
Then I need to remove the intere course with id="112233" of the user "john" using an angular code.
So I use this code, but it doesn't work:
this.http.put('http://localhost:2403/users/1',
{ "courses": { $pull: { "id": 112233 } }
}).subscribe( ..... )
Deployd API returns me a positive message, but the course is not really removed from the user object.
Can anyone help me?

Stacked Column combined with Line

We need to display a stacked column chart combined with a line chart and would like to stick to the VizFrame control offered by UI5. Is there a way to achieve this? It's not listed in the samples (https://sapui5.netweaver.ondemand.com/sdk/explored.html#/entity/sap.viz.ui5.controls.VizFrame/samples) but maybe there is a way to do it anyway.
EDIT
The data we need to display comes in the following format:
var data = [
{week: 1, stacked1: 10, stacked2: 20, stacked3: 30, line: 100},
{week: 2, stacked1: 12, stacked2: 13, stacked3: 14, line: 40},
{week: 3, stacked1: 14, stacked2: 25, stacked3: 26, line: 20},
{week: 4, stacked1: 15, stacked2: 24, stacked3: 33, line: 52}
];
So the idea is to have weeks on the x-axis, a stacked bar for the values stacked1, stacked2 and stacked3 as well as a value point for the line.
I think you want to use setVizType("stacked_combination") [or vizType: "stacked_combination"] on the VizFrame. You can see all the type on the getVizType() VizFrame doumentation. Here is a simple example where I extended the VizFrame and added two functions to display a Line Stacked Column Chart:
sap.viz.ui5.controls.VizFrame.extend("jonova.ui5.chart.JuVizFrame", {
renderer: { },
setLineStackedBar: function() {
var oModel = new sap.ui.model.json.JSONModel(
[{Product:"Total", Date: 2000, Available: 100},
{Product:"Total", Date: 2001, Available: 100},
{Product:"P1", Date: 2000, Utilized: 30},
{Product:"P1", Date: 2001, Utilized: 20},
{Product:"P2", Date: 2000, Utilized: 40},
{Product:"P2", Date: 2001, Utilized: 60}]);
var oDataset = new sap.viz.ui5.data.FlattenedDataset({
dimensions: [{name: 'Date', value: '{Date}'},
{name: 'Product', value: '{Product}'}],
measures: [{name: 'Available', value: '{Available}'},
{name: 'Utilized', value: '{Utilized}' }],
data: {path: "/"}});
var oFeeds = [new sap.viz.ui5.controls.common.feeds.FeedItem({uid: "valueAxis", type: "Measure", values: ["Utilized", "Available"]}),
new sap.viz.ui5.controls.common.feeds.FeedItem({uid: "categoryAxis", type: "Dimension", values: ["Date"]}),
new sap.viz.ui5.controls.common.feeds.FeedItem({uid: "color", type: "Dimension", values: ["Product"]})];
this.setChart("stacked_combination", oDataset, oModel, oFeeds);
},
setChart: function(aVizType, aDataset, aModel, aFeeds) {
this.setVizType(aVizType);
this.setDataset(aDataset);
this.setModel(aModel);
for( var i=0, len=aFeeds.length; i<len; i++) this.addFeed(aFeeds[i]);
},
});