Multi-Level grouping aggregate with MongoDB - node.js

I have project we are working for, and I have chart of account built with multi-level parent/children
ex.
[
{
"_id": "6339dc11de91f060af6e17e0",
"name": "Cash",
"code": "1",
"codeChain": "1",
"isParent": true
},
{
"_id": "6339dc11de91f060af6e17e1",
"parent": "6339dc11de91f060af6e17e0",
"name": "Cash",
"code": "01",
"codeChain": "1.01",
"isParent": true
},
{
"_id": "6339dc11de91f060af6e17e2",
"parent": "6339dc11de91f060af6e17e1",
"name": "Cash",
"code": "001",
"codeChain": "1.01.001",
"isParent": true
},
{
"_id": "6339dc11de91f060af6e17e3",
"parent": "6339dc11de91f060af6e17e2",
"name": "Cash",
"code": "001",
"codeChain": "1.01.001.001",
"isParent": true
}
// and so on
]
then we need to make a query to get the result of :
[
{
"_id": "6339dc11de91f060af6e17e0",
"name": "Cash",
"code": "1",
"codeChain": "1",
"isParent": true,
"children": [
{
{
"_id": "6339dc11de91f060af6e17e1",
"parent": "6339dc11de91f060af6e17e0",
"name": "Cash",
"code": "01",
"codeChain": "1.01",
"isParent": true,
"children": [
{
"_id": "6339dc11de91f060af6e17e2",
"parent": "6339dc11de91f060af6e17e1",
"name": "Cash",
"code": "001",
"codeChain": "1.01.001",
"isParent": true,
"children": [
{
"_id": "6339dc11de91f060af6e17e3",
"parent": "6339dc11de91f060af6e17e2",
"name": "Cash",
"code": "001",
"codeChain": "1.01.001.001",
"isParent": true
}
]
}
]
}
}
]
}
// and so on
]
NOTED THAT : We don't know how deep it could be, and also we have other collections with the transactions we will link it later
Or should we change all the data structure to serve that need !

Related

Typescript to update Mongodb

Got thrown into a Typescript/Mongodb project and am having some trouble getting started. I've been asked to convert data from
{
"_id": {
"$oid": "636c0a8dce0eb36dc13e63b3"
},
"status": "active",
"companies": [
{
"$oid": "5f64bd6785fad3e83771bb4f"
}
],
"whitelists": [],
"taxonomies": [
{
"$oid": "6080538565c2036dbeadcdfa"
},
{
"$oid": "6080538765c2036dbeadce07"
},
{
"$oid": "6080538d65c2036dbeadce44"
},
{
"$oid": "6080538d65c2036dbeadce46"
}
],
"itemType": "unit",
"attributes": [
{
"_id": {
"$oid": "6384d2bdf29f40634fe77db4"
},
"type": "ingredients:statement",
"key": "0",
"parent": "nutrition:panel#0",
"uid": "ingredients:statement#0",
"value": {
"footnotes": [],
"statement": "ingredients: water, butter, lemon juice, wheat flour, egg yolks, sea salt, xanthan gum, turmeric, carotenes."
}
},
{
"_id": {
"$oid": "6384d2bdf29f40634fe77db5"
},
"type": "allergens",
"key": "0",
"parent": "nutrition:panel#0",
"uid": "allergens#0",
"value": {
"type": "contains",
"statement": "contains something"
}
},
{
"_id": {
"$oid": "6384d2bdf29f40634fe77db5"
},
"type": "allergens",
"key": "0",
"parent": "nutrition:panel#0",
"uid": "allergens#0",
"value": {
"type": "something",
"statement": "may contain something"
}
},
{
"_id": {
"$oid": "6384d2bdf29f40634fe77db6"
},
"type": "variants:flavors:raw",
"key": "0",
"parent": "nutrition:panel#0",
"uid": "variants:flavors:raw#0",
"value": [
"hollandaise sauce"
]
}
],
"dataUpdatedDate": {
"$date": {
"$numberLong": "1668025007811"
}
}
}
To something like this, merging objects with the same "type" "b"
{
"_id": {
"$oid": "636c0a8dce0eb36dc13e63b3"
},
"status": "active",
"companies": [
{
"$oid": "5f64bd6785fad3e83771bb4f"
}
],
"whitelists": [],
"taxonomies": [
{
"$oid": "6080538565c2036dbeadcdfa"
},
{
"$oid": "6080538765c2036dbeadce07"
},
{
"$oid": "6080538d65c2036dbeadce44"
},
{
"$oid": "6080538d65c2036dbeadce46"
}
],
"itemType": "unit",
"attributes": [
{
"_id": {
"$oid": "6384d2bdf29f40634fe77db4"
},
"type": "ingredients:statement",
"key": "0",
"parent": "nutrition:panel#0",
"uid": "ingredients:statement#0",
"value": {
"footnotes": [],
"statement": "ingredients: water, butter, lemon juice, wheat flour, egg yolks, sea salt, xanthan gum, turmeric, carotenes."
}
},
{
"_id": {
"$oid": "6384d2bdf29f40634fe77db5"
},
"type": "allergens",
"key": "0",
"parent": "nutrition:panel#0",
"uid": "allergens#0",
"value": [{
"type": "contains",
"statement": "contains something"
},
{
"type": "something",
"statement": "may contain something"
}
]},
{
"_id": {
"$oid": "6384d2bdf29f40634fe77db6"
},
"type": "variants:flavors:raw",
"key": "0",
"parent": "nutrition:panel#0",
"uid": "variants:flavors:raw#0",
"value": [
"hollandaise sauce"
]
}
],
"dataUpdatedDate": {
"$date": {
"$numberLong": "1668025007811"
}
}
}
My background is php/mysql. I understand the basics here just can't put it together. Any help would be greatly appreciated.
Thanks
I have the basics of the typescript started to grab all the appropriate documents. I don't know how to go about combining some of the data and updating it back to mongo
Here is the basic code I am starting with
makeScript({
module,
db: true,
init: async _argv => {
await Pv2.find({
attributes: {
$elemMatch: {
type: 'allergens'
},
},
})
.limit(10)
.cursor()
.eachAsync(async (oldPv2s: Pv2Doc | Pv2Doc[]) => {
// not sure what goes here
});
}
});

Text length ValidationError in STRAPI with CKEditor

I am using STRAPI with custom rich text editor. I setup from this docs
Now If I write more than 234 word I gives ValidationError in console.
I am trying to increase max text limit but I am not sure it is possible or not and from where we can increase word limit.
Here is I am using STRAPI version v3.6.2
{
"name": "ValidationError",
"value": {
"id": 1,
"title": "news1 edited",
"description": "<p>asssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddDDSDSFd</p>",
"published_at": "2021-11-17T07:19:43.837Z",
"created_by": {
"registrationToken": null,
"lastname": "user",
"preferedLanguage": null,
"blocked": null,
"resetPasswordToken": null,
"isActive": true,
"username": "username",
"id": 1,
"firstname": "user",
"email": "user#email.com"
},
"updated_by": {
"registrationToken": null,
"lastname": "user",
"preferedLanguage": null,
"blocked": null,
"resetPasswordToken": null,
"isActive": true,
"username": "username",
"id": 1,
"firstname": "user",
"email": "user#email.com"
},
"created_at": "2021-11-17T07:09:34.551Z",
"updated_at": "2021-12-06T03:22:38.714Z"
},
"errors": [
"components.Input.error.validation.maxLength"
],
"inner": [
{
"name": "ValidationError",
"value": "<p>asssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddDDSDSFd</p>",
"path": "description",
"type": "max",
"errors": [
"components.Input.error.validation.maxLength"
],
"inner": [],
"message": "components.Input.error.validation.maxLength",
"params": {
"path": "description",
"value": "<p>asssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddDDSDSFd</p>",
"originalValue": "<p>asssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddsdsdsdsdsdsdsdsdsdasssadsdsdsdsdsddDDSDSFd</p>",
"max": 240
}
}
],
"message": "components.Input.error.validation.maxLength"
}

Joining only matching elements

I want to join more than two collections in MongoDB . Is it possible to join?
I have 2 collections and I want to join them based by their ids
news collection
{
"lang": "ru",
"news": [{
"title": "title",
"content": "desc",
"image": "path",
"categoryId": {
"$oid": "6171499e0ba3d75082823c9a"
},
"createdAt": {
"$date": "2021-10-21T12:30:33.215Z"
},
"_id": {
"$oid": "61715d7990905adefcf314d1"
}
}]
}
and I have got newscategory collection like that
[
{
"lang": "ru",
"categories": [{
"name": "sdfsdsdcsdf",
"_id": {
"$oid": "6171499e0ba3d75082823c9a"
}
}]
},
{
"lang": "en",
"categories": [{
"name": "ooo",
"_id": {
"$oid": "61712980f8ee795c6a569dcb"
}
}, {
"name": "yuy",
"_id": {
"$oid": "61712980f8ee795c6a569dcc"
}
}, {
"name": "rtyrty",
"_id": {
"$oid": "61712980f8ee795c6a569dcd"
}
}]
}
]
Expected Output:
[
{
"_id": "61715d7990905adefcf314d0",
"lang": "ru",
"news": [
{
"title": "sdf",
"content": "sdf",
"image": "asdas",
"categoryId": "6171499e0ba3d75082823c9a",
"caregory": [
{
"name": "sdfsdsdcsdf",
"_id": "6171499e0ba3d75082823c9a"
},
]
"createdAt": "2021-10-21T12:30:33.215Z",
"_id": "61715d7990905adefcf314d1"
}
],
Match is based on both "category_id" and "categories._id".
How can I achieve result like that ?

How to join related tree repository with TypeORM

I have this situation:
This is my tree entity where each item can be a parent item or child item of one of the same entity and each of them are related to an artist.
#Entity()
#Tree("materialized-path")
export class ArtistCommissionSetupItem {
#PrimaryGeneratedColumn({type: "bigint"})
id:number
#ManyToOne(()=>Artist, artist => artist.id, {onDelete: 'CASCADE'})
#JoinColumn()
#Index()
artist:Artist
#Column()
#Index()
name:string
#Index()
#Column({nullable: true})
enabled:boolean
#TreeParent()
parent:ArtistCommissionSetupItem
#TreeChildren()
childrens:ArtistCommissionSetupItem[]
}
The thing here is that I want to get the artist with his related commission setup items and I can do that but the result of commission setup items leftJoinAndSelect method doesn't come with the items nested as tree/child tree. I want the data of commission setup items come like findTrees() method returns it.
An example of how the data come:
"commissionSetupItems": [
{
"id": "154",
"name": "Body",
"enabled": null,
"price": null,
"createdAt": "2021-09-23T21:17:05.630Z",
"updatedAt": "2021-09-23T21:17:05.630Z"
},
{
"id": "155",
"name": "icon",
"enabled": true,
"price": "120.00",
"createdAt": "2021-09-23T21:17:05.630Z",
"updatedAt": "2021-09-23T21:17:05.630Z"
},
{
"id": "156",
"name": "Headshot",
"enabled": false,
"price": "120.00",
"createdAt": "2021-09-23T21:17:05.630Z",
"updatedAt": "2021-09-23T21:17:05.630Z"
}
}
an example of how I want the data comes:
{
"commissionSetupItems": [
{
"id": 1,
"name": "Characters",
"key": "characters",
"childrens": [
{
"id": 5,
"name": "Number of characters",
"key": "number_of_characters",
"childrens": []
}
]
},
{
"id": 2,
"name": "Body",
"key": "body",
"childrens": [
{
"id": 6,
"name": "Icon",
"key": "icon",
"childrens": []
},
{
"id": 7,
"name": "Chibi",
"key": "chibi",
"childrens": []
},
{
"id": 8,
"name": "Headshot",
"key": "headshot",
"childrens": []
},
{
"id": 9,
"name": "Torso or Burst",
"key": "torso",
"childrens": []
},
{
"id": 10,
"name": "Half body",
"key": "half_body",
"childrens": []
},
{
"id": 11,
"name": "Full body",
"key": "full_body",
"childrens": []
}
]
}
}
I can't figure out how to do this.

MongoDB create product summary collection

Say I have a product collection like this:
{
"_id": "5a74784a8145fa1368905373",
"name": "This is my first product",
"description": "This is the description of my first product",
"category": "34/73/80",
"condition": "New",
"images": [
{
"length": 1000,
"width": 1000,
"src": "products/images/firstproduct_image1.jpg"
},
...
],
"attributes": [
{
"name": "Material",
"value": "Synthetic"
},
...
],
"variation": {
"attributes": [
{
"name": "Color",
"values": ["Black", "White"]
},
{
"name": "Size",
"values": ["S", "M", "L"]
}
]
}
}
and a variation collection like this:
{
"_id": "5a748766f5eef50e10bc98a8",
"name": "color:black,size:s",
"productID": "5a74784a8145fa1368905373",
"condition": "New",
"price": 1000,
"sale": null,
"image": [
{
"length": 1000,
"width": 1000,
"src": "products/images/firstvariation_image1.jpg"
}
],
"attributes": [
{
"name": "Color",
"value": "Black"
},
{
"name": "Size",
"value": "S"
}
]
}
I want to keep the documents separate and for the purpose of easy browsing, searching and faceted search implementation, I want to fetch all the data in a single query but I don't want to do join in my application code.
I know it's achievable using a third collection called summary that might look like this:
{
"_id": "5a74875fa1368905373",
"name": "This is my first product",
"category": "34/73/80",
"condition": "New",
"price": 1000,
"sale": null,
"description": "This is the description of my first product",
"images": [
{
"length": 1000,
"width": 1000,
"src": "products/images/firstproduct_image1.jpg"
},
...
],
"attributes": [
{
"name": "Material",
"value": "Synthetic"
},
...
],
"variations": [
{
"condition": "New",
"price": 1000,
"sale": null,
"image": [
{
"length": 1000,
"width": 1000,
"src": "products/images/firstvariation_image.jpg"
}
],
"attributes": [
"color=black",
"size=s"
]
},
...
]
}
problem is, I don't know how to keep the summary collection in sync with the product and variation collection. I know it can be done using mongo-connector but i'm not sure how to implement it.
please help me, I'm still a beginner programmer.
you don't actually need to maintain a summary collection, its redundant to store product and variation summary in another collection
instead of you can use an aggregate pipeline $lookup to outer join product and variation using productID
aggregate pipeline
db.products.aggregate(
[
{
$lookup : {
from : "variation",
localField : "_id",
foreignField : "productID",
as : "variations"
}
}
]
).pretty()

Resources