TreeModel.parse pass array? - treemodel

I'm using the TreeModel js library. It looks like the library supports passing a object that has a structure like...
{
id: 1,
children: [{
id: 2,
childre: []
}]
}
However, what if I have a tree structure that is an array like...
[
{
id: 1,
children: [],
},
{
id: 2,
children: [
id: 5,
children []
]
}
]
Does the library not support passing an array? Thoughts on how best to deal with this?

You can create a fake root (id=0) whose children are your array:
{
id: 0,
children: [
{
id: 1,
children: [],
},
{
id: 2,
children: [
id: 5,
children []
]
}
]
}

Related

Filtering items within object that is multiple level down with MongoQuery

Please consider below model.
interface Model {
title: string
content: string
comments: {
content: string
likes?: number
subComments: {
parentCommentId: string
content: string
likes?: number
}[]
}[]
}
const post: Model = {
title: 'test',
content: 'content',
comments: [
{
content: 'level2',
likes: 3,
subComments: [
{
parentCommentId: '1',
content: 'level3',
likes: 3,
},
],
},
{
content: 'level2',
likes: 3,
subComments: [
{
parentCommentId: '1',
content: 'level3',
likes: 5,
},
{
parentCommentId: '1',
content: 'level3',
likes: 5,
},
],
},
],
}
Let's say we have a post that has comment that has subComment.
The level of subComment is at level 3 but the depth is fixed.
Is there a way to filter subComments that has optional key "likes" and whose value is greater than 3 with MongoClient?
I don't know exactly what output do you want but you can try something like this example using only projection into find query:
Here there are two $filter and one map.
The $map get each object into comments array and:
Set the content as it is: content: "$$comment.content"
Set the subcomment as an array filtered only by these one objects where likes is greater than 3.
*I've not added likes because it seems no congruent but can be added using likes: "$$comment.likes"
So this produce an array with only obbjects where there are more than 3 likes.
That's mean it can produce an empty subComments array. So the result of the $map is used into another $filter to get only object where subComments is not empty (i.e. there is at least one comment with more than 3 likes).
db.collection.find({},
{
title: 1,
content: 1,
comments: {
$filter: {
input: {
$map: {
input: "$comments",
as: "comment",
in: {
content: "$$comment.content",
subComments: {
$filter: {
input: "$$comment.subComments",
as: "subComment",
cond: {
$gt: [
"$$subComment.likes",
3
]
}
}
}
}
}
},
cond: {
$ne: [
"$$this.subComments",
[]
]
}
}
}
})
Example here.
Which is also the same to use $project in an aggregate query: example

[MongoDB]: Changing the type of values in all array fields

I have the authors and books test collections which have a many-to-many relationship between them.
> db.books.find()
[
{
_id: ObjectId("60a676f24312c6d8ea7bd6ec"),
title: '300 years of peanut juggling: A longitudinal analysis.',
inPrint: true,
authors: [ '60a673c44312c6d8ea7bd6e9', '60a673c44312c6d8ea7bd6ea' ]
},
{
_id: ObjectId("60a676f24312c6d8ea7bd6ed"),
title: "Mystery Overflow: murder and chaos on the Web's biggest developer Q & A platform.",
inPrint: true,
authors: [ '60a673c44312c6d8ea7bd6eb' ],
edition: 2
}
]
> db.authors.find()
[
{
_id: ObjectId("60a673c44312c6d8ea7bd6e9"),
name: 'Jason Filippou',
age: 33,
nationalities: [ 'GRC, CND' ],
books: [ '60a676f24312c6d8ea7bd6ec' ]
},
{
_id: ObjectId("60a673c44312c6d8ea7bd6ea"),
name: 'Mary Chou',
age: 39,
nationalities: [ 'USA' ],
books: [ '60a676f24312c6d8ea7bd6ec' ]
},
{
_id: ObjectId("60a673c44312c6d8ea7bd6eb"),
name: 'Max Schwarz',
age: 42,
job: 'pilot',
books: [ '60a676f24312c6d8ea7bd6ed' ]
}
]
I implement the relationship externally, as can be seen by the authors and books fields. However, I have made the mistake of having the arrays of references be raw strings, instead of ObjectId types. This means that my joins as required by, e.g, $lookup()) fail.
I tried to mass update all the strings to make them ObjectIds using the command:
db.books.find({}).forEach(book => book.authors.forEach(id => ObjectId(id)))
While the command worked, the original data did not change:
> db.books.find({}).forEach(book => book.authors.forEach(id => ObjectId(id)))
> db.books.find()
[
{
_id: ObjectId("60a676f24312c6d8ea7bd6ec"),
title: '300 years of peanut juggling: A longitudinal analysis.',
inPrint: true,
authors: [ '60a673c44312c6d8ea7bd6e9', '60a673c44312c6d8ea7bd6ea' ]
},
{
_id: ObjectId("60a676f24312c6d8ea7bd6ed"),
title: "Mystery Overflow: murder and chaos on the Web's biggest developer Q & A platform.",
inPrint: true,
authors: [ '60a673c44312c6d8ea7bd6eb' ],
edition: 2
}
]
> db.authors.find()
[
{
_id: ObjectId("60a673c44312c6d8ea7bd6e9"),
name: 'Jason Filippou',
age: 33,
nationalities: [ 'GRC, CND' ],
books: [ '60a676f24312c6d8ea7bd6ec' ]
},
{
_id: ObjectId("60a673c44312c6d8ea7bd6ea"),
name: 'Mary Chou',
age: 39,
nationalities: [ 'USA' ],
books: [ '60a676f24312c6d8ea7bd6ec' ]
},
{
_id: ObjectId("60a673c44312c6d8ea7bd6eb"),
name: 'Max Schwarz',
age: 42,
job: 'pilot',
books: [ '60a676f24312c6d8ea7bd6ed' ]
}
]
What is my mistake here?
If you decide to update all books string to ObjectId, u can use update-documents-with-aggregation-pipeline
db.authors.updateMany({},[
{
"$addFields": {
"books": {
"$map": {
"input": "$books",
"in": {
"$toObjectId": "$$this"
}
}
}
}
}
])

Dart/Flutter How to access element of Map inside a list

How to access a Map element value by key, when a Map is inside a list?
'rooms': [
{
'roomNumber': 1,
'roomBeds': 1,
'roomColor': 1,
'roomNumOfDwellers': 0,
'roomDwellers': [
]
},
{
'roomNumber': 2,
'roomBeds': 3,
'roomColor': 2,
'roomNumOfDwellers': 0,
'roomDwellers': [
]
},
]
Tried this, doesn't work:
myPODO.rooms[1].['roomBeds']
The error message is:
Class '_InternalLinkedHashMap' has no instance getter 'roomBeds'.
Receiver: _LinkedHashMap len:5
Tried calling: roomBeds
Store the items in a list of Map and you can then print the values by key names.
void main() {
List<Map<String, dynamic>> rooms = [
{
'roomNumber': 1,
'roomBeds': 1,
'roomColor': 1,
'roomNumOfDwellers': 0,
'roomDwellers': [
]
},
{
'roomNumber': 2,
'roomBeds': 3,
'roomColor': 2,
'roomNumOfDwellers': 0,
'roomDwellers': [
]
},
];
print(rooms[1]['roomBeds']);
}
try to replace
myPODO.rooms[1].['roomBeds']
with
myPODO.rooms[1]['roomBeds']

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?

Move elements from $pull to another array

I have many documents in the same collection that look like this:
{
"_id": ObjectId("4d525ab2924f0000000022ad"),
"array": [
{ id: 1, other: 23 },
{ id: 1, other: 21 },
{ id: 0, other: 235 },
{ id: 1, other: 765 }
],
"zeroes": []
}
and I want them to look like this:
{
"_id": ObjectId("4d525ab2924f0000000022ad"),
"array": [
{ id: 1, other: 23 },
{ id: 1, other: 21 },
{ id: 1, other: 765 }
],
"zeroes": [
{ id: 0, other: 235 }
]
}
Basically, I want to be able to pull some elements in an array, and push it to another array. I know I can use $pull to conditionally remove elements from an array, but is it possible to relocate these pulled elements?
Not really. You can use cursor for operation like this.
db.foo.find({}).forEach(function(doc) {
doc.zeros = doc.array.filter(function(x) { return x.id == 0 });
doc.array = doc.array.filter(function(x) { return x.id != 0 });
db.foo.save(doc)};
)