aggregate in mongodb left join with $lookup - mongodb-query

I have three collections
posts=[
{
"id": "p1",
"title": "title 1"
},
{
"id": "p2",
"title": "title 2"
}]
users = [
{
"id": "u1",
"name": "name1"
},
{
"id": "u2",
"name": "name2"
}]
comments = [
{
"userId": "u1",
"postId": "p1",
"comment": "comment 1"
}]
I want to get all collection posts and comments in each post by userId(u1) as:
posts=[
{
"id": "p1",
"title": "title 1",
"comments":[
"userId": "u1",
"comment": "comment 1"
]
},
{
"id": "p2",
"title": "title 2",
"comments":[]
}]
I used aggregate function and $lookup operator but I don't know using the $match operator to filter userId. I used aggregate bellow:
self.db.posts.aggregate([
{
"$lookup":{
"from": "comments",
"localField": "id",
"foreignField": "postId",
"as": "comments",
}
},
{
"$match":{
"comments.userId": {"$eq": param.objectUserId}
},
},
{"$skip": (param.page - 1) * param.pageSize},
{"$limit": param.pageSize},
{"$sort": {"unixDate": pymongo.DESCENDING}}
])
It only return one post in array corresponding with userId="u1"
Please help me!
Thank all!

You have to make use of the pipeline option of $lookup stage and pass the additional conditions that you want to apply.
db.posts.aggregate([
{
"$lookup": {
"from": "comments",
"let": {
"pId": "$id"
},
"pipeline": [
{
"$match": {
"$expr": {
"$eq": [
"$postId",
"$$pId"
],
},
"userId": "u1",
},
},
{
"$project": {
"_id": 0,
"userId": 1,
"comment": 1,
},
},
],
"as": "comments"
}
}
])
Mongo Playground Sample Execution
self.db.posts.aggregate([
{
"$lookup": {
"from": "comments",
"let": {
"pId": "$id"
},
"pipeline": [
{
"$match": {
"$expr": {
"$eq": [
"$postId",
"$$pId"
],
},
"userId": param.objectUserId,
},
},
{
"$project": {
"_id": 0,
"userId": 1,
"comment": 1,
},
},
],
"as": "comments"
}
},
{"$skip": (param.page - 1) * param.pageSize},
{"$limit": param.pageSize},
{"$sort": {"unixDate": pymongo.DESCENDING}}
])

Related

how to solve this error in mongodb aggregation: TypeError: ({$unwind:{path:"$tags", preserveNullAndEmptyArrays:true}}) is not iterable :

i have a collection
[{
"_id": {"$oid": "63873b95c7e956270e734f3c"},
"employeeId": "emp1",
"users": [{"name": "Allen","registered": true},
{"name": "Henry","registered": true},
{"name": "Adam","registered": false}],
"tags": ["good","excellent","average"]
},{
"_id": {"$oid": "63873c05c7e956270e734f3d"},
"employeeId": "emp2",
"users": [{"name": "Federick","registered": false},
{"name": "Mary","registered": true},
{"name": "Sam","registered": false} ],
"tags": ["poor","excellent", "good"]}
,{
"_id": {"$oid": "63873c1fc7e956270e734f3e"},
"employeeId": "emp3",
"users": [ {"name": "john", "registered": true},
{"name": "jack","registered": true},
{"name": "elle", "registered": false } ],
"tags": ["very good", "excellent", "good" ]}]
i am trying to groupby tags and employee with count of employees under each tag,expected output is
i am getting the correct output by python code which is
pipeline = [{"$unwind":"$users"},{"$match":{"users.registered":True}},
{"$unwind":"$tags"},
{
"$group": {
"_id": "$tags","employees":{"$push": {"employeeId":"$employeeId"}},
"employees" : { "$addToSet" : "$employeeId" },
"count": {
"$sum": 1
}
}
},
{"$project":{"_id":1,"employees":1,"size":{"$size":"$employees"}}},
{"$sort" : { "size": -1 } },
]
rec = db.ratings.aggregate(pipeline)
but its giving error in mongoshell
Is this what you want?
db.collection.aggregate([
{
"$unwind": "$tags"
},
{
"$group": {
"_id": "$tags",
"employees": {
"$push": "$employeeId"
}
}
},
{
"$project": {
"_id": 1,
"employees": 1,
"size": {
"$size": "$employees"
}
}
},
{
"$sort": {
"size": -1
}
}
])
See how it works on the playground example

Shopware 6 API / Product Listing / How to add available color variants for each product on the response

API Request
/store-api/product-listing/{categoryId}
I want each product in the API response to have available color variants. Because I want to show color variants on the product list page. But currently this data is not provided by the shopware 6 api.
I've tried to add this data by using associations but it didnt help.
Request Body
{
"includes": {
"product": ["id", "productNumber", "cover", "options"]
},
"associations": {
"options": {
"media": []
}
}
}
The request body looks to be correct. If the product is a variant then it should have content for options.
To verify try the following request body:
{
"limit": 1,
"includes": {
"product": ["id", "productNumber", "options"],
"property_group_option": ["name", "group"],
"property_group": ["name"]
},
"associations": {
"options": {
"associations": {
"group": []
}
}
},
"filters": [
{
"type": "not",
"operator": "and",
"queries": [
{
"type": "equals",
"field": "parentId",
"value": null
}
]
}
]
}
This should yield a single variant.
Response should look similar to this:
{
"entity": "product",
"total": 1,
"aggregations": [],
"page": 1,
"limit": 1,
"elements": [
{
"productNumber": "10042.1",
"options": [
{
"name": "linen",
"group": {
"name": "textile",
"apiAlias": "property_group"
},
"apiAlias": "property_group_option"
},
{
"name": "35",
"group": {
"name": "size",
"apiAlias": "property_group"
},
"apiAlias": "property_group_option"
},
{
"name": "chartreuse",
"group": {
"name": "shirt-color",
"apiAlias": "property_group"
},
"apiAlias": "property_group_option"
}
],
"id": "0002ea44c49c41ecb91c43e7e49e422d",
"apiAlias": "product"
}
],
"states": [],
"apiAlias": "dal_entity_search_result"
}

How to parse a JSON with missing property name into a db table

I am trying to convert JSON into an SQL table. The source is the response from a REST API. I do not have the opportunity to change the response.
The response contains data on several projects. Projects are returned as individual members of a global projects object.
As the projectid is not at the same level with the other data and also does not have a name
SELECT * FROM OPENJSON (#JSON);
fails to parse it properly. I end up with one row for projects and the json object as the value. Also without the proper way to refer to the elements I could not figure out a way to use JSON_VALUE.
Below is a sample structure. Actual data has much more properties and variations between the projects. I prefer to solve this in SQL. But any way to sort out the JSON will be appreciated. This is my first exposure to JSON. I want to ask if I am missing something very obvious...
TIA
{
"projects": {
"project1id": {
"data": {
"customer": "Cust1",
"name": "Project Name 1"
},
"projectType": "type0"
},
"project2id": {
"data": {
"customer": "Customer 2",
"name": "Name 2",
"projectManager": "Man Ager"
},
"projectType": "type2"
},
"Project3id": {
"data": {
"customer": "Another Customer",
"name": "Another Project"
},
"projectType": "type1"
}
}
}
Expected Result
ProjectId
Project Name
Customer
Project Type
Project Manager
project1id
Project Name 1
Cust 1
type0
project2id
Customer 2
type2
Man Ager
project3id
Another Project
Another Customer
type1
Excerpt from original Json:
{
"projects": {
"10000eumbvqn76": {
"data": {
"inquiryNumber": "34635",
"customer": "C AS",
"name": "E W ",
"orderNumber": "1000",
"seller": "M A",
"projectManager": "B O V",
"phase": "fulfillment",
"exchange": {
"deadline": {
"time": [
24,
0
],
"timezone": [
1,
0
]
},
"settings": {
"client": {
"codes": [
{
"id": "1",
"label": "Code 1"
},
{
"id": "4",
"label": "Code 4"
},
{
"id": "5",
"label": "Code 5"
},
{
"id": "2",
"label": "Code 2"
},
{
"id": "3",
"label": "Code 3"
}
],
"approvedCodes": [
"1"
],
"cycles": {
"producer": 21,
"consumer": 21
}
},
"clientForInformation": {
"cycles": {
"producer": 21
}
},
"supplier": {
"codes": [
{
"id": "1",
"label": "Code 1"
},
{
"id": "4",
"label": "Code 4"
},
{
"id": "5",
"label": "Code 5"
},
{
"id": "2",
"label": "Code 2"
},
{
"id": "3",
"label": "Code 3"
}
],
"approvedCodes": [
"1"
],
"cycles": {
"producer": 14,
"consumer": 14
}
},
"supplierIsProducer": {
"supplierRole": "producer"
},
"supplierIsConsumer": {
"supplierRole": "consumer"
}
},
"sequences": {
"$salesPurchase": {
"label": "Client RFQ to OC",
"settings": "supplierIsProducer",
"group": "inquiry"
},
"$salesPurchaseSupplier": {
"label": "Supplier RFQ to OC",
"settings": "supplierIsConsumer",
"group": "inquiry"
},
"$salesClient": null,
"$salesClientFrom": null,
"$client": {
"label": "To client",
"group": "order-fulfillment",
"order": [
"IFR",
"IFI"
],
"stages": {
"IFR": {
"label": "Issued for Review",
"phase": "forApproval",
"settings": "client"
},
"IFI": {
"label": "Issued for Information",
"phase": "forInformation",
"settings": "clientForInformation"
}
},
"interpret": {
"type": "unordered"
}
},
"$supplier": {
"label": "From supplier",
"group": "order-fulfillment-supplier",
"settings": "supplier"
},
"$supplierTo": {
"label": "To supplier",
"group": "order-fulfillment-supplier",
"settings": "supplierIsConsumer"
},
"$internal": null
}
},
"officialMailIdFormat": "M-1000-0001",
"transmittalMailIdFormat": "TR-1000-0001",
"commercialMailIdFormat": "Bid-34635-0001",
"officialMailIdFormats": [
{
"label": "Official",
"format": "M-1000-0001"
},
{
"label": "Commercial",
"format": "Bid-34635-0001"
}
]
},
"projectType": "commercial"
},
"1000hf30ua": {
"data": {
"inquiryNumber": "100",
"customer": "S M I Y P L",
"name": "1000 FSPO ",
"seller": "L H",
"projectManager": "L H",
"phase": "inquiry",
"exchange": {
"deadline": {
"time": [
24,
0
],
"timezone": [
1,
0
]
},
"settings": {
"client": {
"codes": [
{
"id": "1",
"label": "Code 1"
},
{
"id": "4",
"label": "Code 4"
},
{
"id": "5",
"label": "Code 5"
},
{
"id": "2",
"label": "Code 2"
},
{
"id": "3",
"label": "Code 3"
}
],
"approvedCodes": [
"1"
],
"cycles": {
"producer": 21,
"consumer": 21
}
},
"clientForInformation": {
"cycles": {
"producer": 21
}
},
"supplier": {
"codes": [
{
"id": "1",
"label": "Code 1"
},
{
"id": "4",
"label": "Code 4"
},
{
"id": "5",
"label": "Code 5"
},
{
"id": "2",
"label": "Code 2"
},
{
"id": "3",
"label": "Code 3"
}
],
"approvedCodes": [
"1"
],
"cycles": {
"producer": 14,
"consumer": 14
}
},
"supplierIsProducer": {
"supplierRole": "producer"
},
"supplierIsConsumer": {
"supplierRole": "consumer"
}
},
"sequences": {
"$salesPurchase": {
"label": "Client RFQ to OC",
"settings": "supplierIsProducer",
"group": "inquiry"
},
"$salesPurchaseSupplier": {
"label": "Supplier RFQ to OC",
"settings": "supplierIsConsumer",
"group": "inquiry"
},
"$salesClient": null,
"$salesClientFrom": null,
"$client": {
"label": "To client",
"group": "order-fulfillment",
"order": [
"IFR",
"IFI"
],
"stages": {
"IFR": {
"label": "Issued for Review",
"phase": "forApproval",
"settings": "client"
},
"IFI": {
"label": "Issued for Information",
"phase": "forInformation",
"settings": "clientForInformation"
}
},
"interpret": {
"type": "unordered"
}
},
"$supplier": {
"label": "From supplier",
"group": "order-fulfillment-supplier",
"settings": "supplier"
},
"$supplierTo": {
"label": "To supplier",
"group": "order-fulfillment-supplier",
"settings": "supplierIsConsumer"
},
"$internal": null
}
},
"officialMailIdFormat": "M-100-0001",
"transmittalMailIdFormat": "TR-100-0001",
"commercialMailIdFormat": "Bid-100-0001",
"officialMailIdFormats": [
{
"label": "Official",
"format": "M-100-0001"
},
{
"label": "Commercial",
"format": "Bid-100-0001"
}
],
"orderNumber": "100"
},
"projectType": "commercial"
}
}
}
Possible options are: 1) Using OPENJSON() twice (with default and explicit schema) and an additional APPLY operator or 2) Using OPENJSON() (with default schema) and JSON_VALUE():
JSON:
DECLARE #json nvarchar(max) = N'{
"projects":{
"project1id":{
"data":{
"customer":"Cust1",
"name":"Project Name 1"
},
"projectType":"type0"
},
"project2id":{
"data":{
"customer":"Customer 2",
"name":"Name 2",
"projectManager":"Man Ager"
},
"projectType":"type2"
},
"Project3id":{
"data":{
"customer":"Another Customer",
"name":"Another Project"
},
"projectType":"type1"
}
}
}'
Statement with OPENJSON() and APPLY operator:
SELECT j1.[key] AS projectId, j2.*
FROM OPENJSON(#json, '$.projects') j1
CROSS APPLY OPENJSON(j1.[value], '$') WITH (
name nvarchar(100) '$.data.name',
customer nvarchar(100) '$.data.customer',
projectType nvarchar(100) '$.projectType',
projectManager nvarchar(100) '$.data.projectManager'
) j2
Statement with OPENJSON() and JSON_VALUE():
SELECT
projectId = [key],
name = JSON_VALUE([value], '$.data.name'),
customer = JSON_VALUE([value], '$.data.customer'),
projectType = JSON_VALUE([value], '$.projectType'),
projectManager = JSON_VALUE([value], '$.data.projectManager')
FROM OPENJSON(#json, '$.projects')

Problem to fetch data in api call in flutter/dart

how can I fetch the name and team_name keys in this API data?
condition: here 18,1,17, etc are subject codes that change according to the subject and not fix this subject available in the next API call.
{
"18": {
"detail": {
"id": "18",
"name": "Hindi"
},
"list": [
{
"id": "5",
"team_name": "Gurpreet",
},
{
"id": "2",
"team_name": "Test1",
}
]
},
"17": {
"detail": {
"id": "17",
"name": "Punjabi"
},
"list": [
{
"id": "6",
"team_name": "Guru",
},
{
"id": "3",
"team_name": "Test",
}
]
},
"1": {
"detail": {
"id": "1",
"name": "History"
},
"list": [
{
"id": "7",
"team_name": "Gurpreet",
}
]
},
"19": {
"detail": {
"id": "19",
"name": "Math"
},
"list": [
{
"id": "4",
"team_name": "Gurpreet",
}
]
},
"status": true
}
Use this code. You can check keys getter to check dynamics key.
import 'dart:convert';
void main() async {
var f = {
"18": {
"detail": {"id": "18", "name": "Hindi"},
"list": [
{
"id": "5",
"team_name": "Gurpreet",
},
{
"id": "2",
"team_name": "Test1",
}
]
},
"17": {
"detail": {"id": "17", "name": "Punjabi"},
"list": [
{
"id": "6",
"team_name": "Guru",
},
{
"id": "3",
"team_name": "Test",
}
]
},
"1": {
"detail": {"id": "1", "name": "History"},
"list": [
{
"id": "7",
"team_name": "Gurpreet",
}
]
},
"19": {
"detail": {"id": "19", "name": "Math"},
"list": [
{
"id": "4",
"team_name": "Gurpreet",
}
]
},
"status": true
};
for (var o in f.keys) {
print(o);
if (f[o] is bool) {
print(f[o]);
} else { // check it is Map. I consider it always is Map
if ((f[o] as Map)['detail'] != null) {
print((f[o] as Map)['detail']['name']);
}
if ((f[o] as Map)['list'] != null) {
print((f[o] as Map)['list'][0]['team_name']); // you can use for here. please check array is not null
}
}
}
}

How to expand tree node without ajax request?

I am using Extjs tree, i got problem with click on nested node ajax request to server, i know this kind of lazy load but my tree is not big, around 35 items so i want request to server time only to collect all tree node and items.
Any idea?
View:
Ext.define('CRM.view.role.RoleTree' ,{
extend: 'Ext.tree.Panel',
alias: 'widget.roleTreeList',
id:'tree-role-panel',
split: false,
autoScroll: true,
lines: true,
singleExpand: false,
store: 'RoleList'
})
Store:
Ext.define('CRM.store.RoleList', {
extend: 'Ext.data.TreeStore',
storeId: 'RoleTreeStoreId',
//model: 'CRM.model.RoleList',
autoLoad: false,
proxy: {
type : 'ajax',
url : 'index.php/role/getRoleList',
async : false,
reader: {
type : 'json',
method : 'POST'
}
},
root:{
expanded:true,
text:"Organization",
leaf:'false',
id : '/',
}
})
Json return:
{
"text": "Organization",
"id": "role-1",
"children": [
{
"text": "Admin",
"id": "role-12",
"expanded": "true",
"children": [
{
"text": "MSD",
"id": "role-23",
"children": [
{
"text": "Customer Care Manager",
"id": "role-4",
"children": [
{
"text": "Customer Care Adviser",
"id": "role-5"
}
]
},
{
"text": "Solution Adviser",
"id": "role-7"
},
{
"text": "Sales Manager",
"id": "role-31",
"children": [
{
"text": "Solution Sales",
"id": "role-6"
},
{
"text": "Teritory 01 - Safy",
"id": "role-9",
"children": [
{
"text": "Sales Person 01",
"id": "role-10"
},
{
"text": "Sales Trainee 01",
"id": "role-26"
}
]
},
{
"text": "Teritory 3 - Sambo",
"id": "role-11",
"children": [
{
"text": "Sales Person 3",
"id": "role-13"
}
]
},
{
"text": "Teritory 4 - Narong",
"id": "role-14",
"children": [
{
"text": "Sales Team 4",
"id": "role-15",
"children": [
{
"text": "Sales Person 4",
"id": "role-25"
}
]
}
]
},
{
"text": "branch shv",
"id": "role-16",
"children": [
{
"text": "sales shv",
"id": "role-19"
}
]
},
{
"text": "branch btb",
"id": "role-17",
"children": [
{
"text": "sales btb",
"id": "role-20"
}
]
},
{
"text": "branch srp",
"id": "role-18",
"children": [
{
"text": "sales srp",
"id": "role-21",
"children": [
{
"text": "sales person srp",
"id": "role-28"
}
]
}
]
},
{
"text": "Retention Program",
"id": "role-22",
"children": [
{
"text": "Retention Program Analysist",
"id": "role-24"
}
]
},
{
"text": "Sales Trainee",
"id": "role-27"
},
{
"text": "Enterprise Sales Engineer",
"id": "role-29"
},
{
"text": "Meas Test",
"id": "role-30"
},
{
"text": "Teritory 02 - Kol",
"id": "role-32",
"children": [
{
"text": "Sales Person 02",
"id": "role-8"
}
]
}
]
}
]
},
{
"text": "CTO",
"id": "role-35",
"children": [
{
"text": "Support Manager",
"id": "role-2",
"children": [
{
"text": "Technical Support Adviser",
"id": "role-3"
}
]
},
{
"text": "IT BIlling Product Manager",
"id": "role-33",
"children": [
{
"text": "IT Staff",
"id": "role-34"
}
]
}
]
},
{
"text": "Business Consultant",
"id": "role-36"
}
]
}
]
}
You can still use asynchronous call, but only once. To make sure only one call is made, return all children in first call. Extjs will load all children provided.
I found my mistake with JSON, i should add property "leaf = true/false" according has child or hasn't.