How to count orders with positions unwind in MongoDB aggregation? - count

I have a collection with order headers and positions (as array) and I need an query which should give me:
quantity of customers
quantity of orders
summed up order value
all grouped by date and order type. I already got this covered by two queries (see below), but I want to have it in one.
The main problem to me is that I need to count the orders but with positions unwinded.
E.g.: Below would be a possible result of the combined query with the test data below:
/* 1 */
{
"_id" : {
"typ" : "WERBUNG",
"date" : "2017-07-08"
},
"orderQuantity" : 1.0,
"value" : 1000,
"customerQuantity" : 1
}
/* 2 */
{
"_id" : {
"typ" : "WERBUNG",
"date" : "2017-07-07"
},
"orderQuantity" : 2.0,
"value" : 100,
"customerQuantity" : 1
}
/* 3 */
{
"_id" : {
"typ" : "ANDERE",
"date" : "2017-07-08"
},
"orderQuantity" : 4.0,
"value" : 1500,
"customerQuantity" : 4
}
/* 4 */
{
"_id" : {
"typ" : "ANDERE",
"date" : "2017-07-07"
},
"orderQuantity" : 1.0,
"value" : 90,
"customerQuantity" : 1
}
... this would mean:
On 7-7 there where 3 orders (WERBUNG 2, ANDERE 1) for only 1 customer (WERBUNG 1, ANDERE 1 - will be counted twice here, bit this would be okay)
On 8-7 there where 5 orders (WERBUNG 1, ANDERE 4) for 5 customers (WERBUNG 4, ANDERE 1)
I have an idea that SortBy would help here, however we still use 3.2 - so no access to this stage (and some other usefull options as well...).
Cheers!
--
Some information which might help:
// Here are the sample orders:
/*1*/
{
"_id" : ObjectId("596075d5be8fc415341c7d43"),
"header" : {
"kundennummer" : "820130",
"auftragsdatum" : 0,
"bestellangaben" : "BLOCK1",
"information1" : "blocktest",
"erstellungsdatum" : 1499493785.25906,
"vorgabeauftragsnummer" : 87475000,
},
"ordertype" : "BLOCK1",
"customernnummer" : "820130",
"ordernumber" : 87475000,
"positions" : [
"artikelnummer" : 1985900,
"menge" : 1,
"bruttopreis" : 1000,
"_id" : ObjectId("596075d5be8fc415341c7d45")
}
],
"date" : "2017-07-08",
"type" : "WERBUNG"
}
/*2*/
{
"_id" : ObjectId("59608f64be8fc415341c7d46"),
"header" : {
"kundennummer" : "944867",
"auftragsdatum" : 0,
"bestellangaben" : "",
"information1" : "blocktest",
"erstellungsdatum" : 1499500356.10022,
"vorgabeauftragsnummer" : 87475001,
},
"ordertype" : "",
"customernnummer" : "944867",
"ordernumber" : 87475001,
"positions" : [
{
"artikelnummer" : 4029300,
"menge" : 1,
"bruttopreis" : 100,
"_id" : ObjectId("59608f64be8fc415341c7d5c")
}
],
"date" : "2017-07-08",
"type" : "ANDERE"
}
/*3*/
{
"_id" : ObjectId("5960925ebe8fc415341c7d5d"),
"header" : {
"kundennummer" : "981927",
"auftragsdatum" : 0,
"bestellangaben" : "",
"information1" : "blocktest",
"erstellungsdatum" : 1499501036.34265,
"vorgabeauftragsnummer" : 87475002,
},
"ordertype" : "",
"customernnummer" : "981927",
"ordernumber" : 87475002,
"positions" : [
},
"artikelnummer" : 4557300,
"menge" : 2,
"bruttopreis" : 100,
"_id" : ObjectId("5960925ebe8fc415341c7d74")
}
],
"date" : "2017-07-08",
"type" : "ANDERE"
}
/*4*/
{
"_id" : ObjectId("5960925ebe8fc415341c7d75"),
"header" : {
"kundennummer" : "981927",
"auftragsdatum" : 0,
"bestellangaben" : "BLOCK2",
"information1" : "blocktest",
"erstellungsdatum" : 1499414714,
"vorgabeauftragsnummer" : 87475003,
},
"ordertype" : "BLOCK2",
"customernnummer" : "981927",
"ordernumber" : 87475003,
"positions" : [
{ "artikelnummer" : 7081200,
"menge" : 3,
"bruttopreis" : 10,
"_id" : ObjectId("5960925ebe8fc415341c7d8f")
}
],
"date" : "2017-07-07",
"type" : "WERBUNG"
}
/*5*/
{
"_id" : ObjectId("596093ebbe8fc415341c7d90"),
"header" : {
"kundennummer" : "962422",
"auftragsdatum" : 0,
"bestellangaben" : "",
"information1" : "blocktest",
"erstellungsdatum" : 1499501507.75201,
"vorgabeauftragsnummer" : 87475004,
},
"ordertype" : "",
"customernnummer" : "962422",
"ordernumber" : 87475004,
"positions" : [
"artikelnummer" : 3545900,
"menge" : 4,
"bruttopreis" : 100,
"_id" : ObjectId("596093ebbe8fc415341c7d95")
}
],
"date" : "2017-07-08",
"type" : "ANDERE"
}
/*6*/
{
"_id" : ObjectId("596098e9be8fc415341c7ddf"),
"header" : {
"kundennummer" : "981927",
"auftragsdatum" : 0,
"bestellangaben" : "BLOCK3",
"information1" : "blocktest",
"erstellungsdatum" : 1499415886,
"vorgabeauftragsnummer" : 87475007,
},
"ordertype" : "BLOCK3",
"customernnummer" : "981927",
"ordernumber" : 87475007,
"positions" : [
{
"artikelnummer" : 1006199,
"menge" : 7,
"bruttopreis" : 10,
"_id" : ObjectId("596098e9be8fc415341c7de6")
}
],
"date" : "2017-07-07",
"type" : "WERBUNG"
}
/*7*/
{
"_id" : ObjectId("59609a47be8fc415341c7de7"),
"header" : {
"kundennummer" : "981225",
"auftragsdatum" : 0,
"bestellangaben" : "",
"information1" : "blocktest",
"erstellungsdatum" : 1499503113.21714,
},
"ordertype" : "",
"customernnummer" : "981225",
"ordernumber" : 87475008,
"positions" : [
{
"_id": ObjectId("59609a47be8fc415341c7e0d")
"artikelnummer" : 2308400,
"menge" : 8,
"bruttopreis" : 100,
}
],
"date" : "2017-07-08",
"type" : "ANDERE"
}
/*8*/
{
"_id" : ObjectId("59609a47be8fc415341c7e0e"),
"header" : {
"vorgabeauftragsnummer" : 87475009,
"erstellungsdatum" : 1499416697,
"information1" : "blocktest",
"bestellangaben" : "",
"auftragsdatum" : 0,
"kundennummer" : "981927",
},
"ordertype" : "",
"customernnummer" : "981927",
"ordernumber" : 87475009,
"positions" : [
"_id" : ObjectId("59609a47be8fc415341c7e57"),
"bruttopreis" : 10,
"menge" : 9,
"artikelnummer" : 8017000
}
],
"date" : "2017-07-07",
"type" : "ANDERE"
}
// Query 1: Quantity of customers and order value by order type (WERBUNG, ANDERE) and day
db.getCollection('orders').aggregate([
{$unwind:"$positions"},
{$project: {
"_id": 1,
customer: "$header.customernnummer",
date: {$}ToString: {format: "%d-%m-%Y", }: {"$add":[ new }(0), {"$multiply": [1000, "$header.erstellungsdate"]}]} }},
edate: "$header.erstellungsdate",
ordertype: "$header.ordertype",
type: {$cond: { if: {$ne: ["$header.ordertype" ,""]} , then: "WERBUNG", else: "ANDERE" }},
value: {$multiply: ["$positions.price","$positions.quantity"]},
}
},
{$group: {
_id: {type: "$type", tag: "$date",customer: "$customer" },
type: {$first: "$type"},
date: {$first: "$date"},
wert: {$sum: "$value" }
}
},
{$project:{
_id : 0,
customer: "$customer",
type: "$type",
date: "$date",
wert: "$wert"
}
}
,{$group: {
_id: {typ: "$type", date: "$date"}, customerQuantity:{$sum:1},
value: {$sum: "$wert"}
}
},
{$sort:{
typ: 1, date: -1
}
}
]}
// Query 2: Order quantity by type, date
...
{$project: {
block: {$cond: { if: {$ne: ["$auftragskopf.bestellangaben" ,""]} , then: "WERBUNG", else: "ANDERE" }},
datum: {$dateToString: {format: "%d-%m-%Y", date: {"$add":[ new Date(0), {"$multiply": [1000, "$auftragskopf.erstellungsdatum"]}]} }},
}
},
{$group:{
_id: {block: "$block", datum: "$datum"},
auftragsanzahl:{$sum:1},
}
},

I'm not sure about how your data looks like, but I understand from this line
type: {$cond: { if: {$ne: ["$header.ordertype" ,""]} , then: "WERBUNG", else: "ANDERE" }}
that if your $header.ordertype is WERBUNG then you want your order type to be WERBUNG otherwise its ANDERE. With that in mind here is my solution.
db.getCollection('orders').aggregate([
{
$project: {
"_id": 1,
header: 1,
positions: 1,
date: {
$dateToString: {
format: "%Y-%m-%d",
date: {
"$add": [new Date(0), {
"$multiply": [1000, "$header.date"]
}]
}
}
},
type: {
$cond: {
if: {
$eq: ["$header.ordertype", "WERBUNG"]
},
then: "WERBUNG",
else: "ANDERE"
}
}
}
},
{
$group: {
_id: {
type: "$type",
date: "$date"
},
werbungCount: {
$sum: {
$cond: [{
$eq: ['$type', 'WERBUNG']
}, 1, 0]
}
},
andereCount: {
$sum: {
$cond: [{
$eq: ['$type', 'ANDERE']
}, 1, 0]
}
},
customer: {
$first: "$header.customernnummer"
},
date: {
$first: "$date"
},
type: {
$first: "$type"
},
positions: {
$first: "$positions"
}
}
},
{
$unwind: "$positions"
},
{
$project: {
"_id": 1,
customer: "$customer",
date: 1,
ordertype: "$header.ordertype",
type: "$type",
value: {
$multiply: ["$positions.price", "$positions.quantity"]
},
price: "$positions.price",
quantity: "$positions.quantity",
orderQuantity: {
$cond: {
if: {
$eq: ["$type", "WERBUNG"]
},
then: "$werbungCount",
else: "$andereCount"
}
},
}
},
{
$group: {
_id: {
type: "$type",
tag: "$date",
customer: "$customer"
},
type: {
$first: "$type"
},
date: {
$first: "$date"
},
wert: {
$sum: "$value"
},
orderQuantity: {
$first: "$orderQuantity"
}
}
},
{
$group: {
_id: {
typ: "$type",
date: "$date"
},
orderQuantity: {
$first: "$orderQuantity"
},
value: {
$sum: "$wert"
}
}
},
{
$sort: {
typ: 1,
date: -1
}
}
])
I use the first $project to "normalize" the date. So an order placed at 1499415886: Friday, July 7, 2017 8:24:46 AM and 1499415990: Friday, July 7, 2017 8:26:30 AM will both be counted since they are on the same date (cause I could also tell from what you wrote that the time doesn't matter to you, only the date)
In the $group after the $project you just count the documents that have the "ordertype" WERBUNG and set them to the field werbungCount, otherwise if they are empty set them to the field andereCount. The pipeline after the $project and the $group is like you did it. I just corrected some mistakes and changed the name of the fields in some spots. Also added the orderQuantity field with a condition on the second $project.
Hope that works!

Related

jq: select only necessary fields if the field n is x

I have the following JSON scheme:
{
"CVE_data_type" : "CVE",
"CVE_data_format" : "MITRE",
"CVE_data_version" : "4.0",
"CVE_data_numberOfCVEs" : "19162",
"CVE_data_timestamp" : "2022-02-24T08:00Z",
"CVE_Items" : [ {
"cve" : {
"data_type" : "CVE",
"data_format" : "MITRE",
"data_version" : "4.0",
"CVE_data_meta" : {
"ID" : "CVE-2020-0597",
"ASSIGNER" : "secure#intel.com"
},
"problemtype" : {
"problemtype_data" : [ {
"description" : [ {
"lang" : "en",
"value" : "CWE-125"
} ]
} ]
},
"references" : {
"reference_data" : [ {
"url" : "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00295.html",
"name" : "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00295.html",
"refsource" : "MISC",
"tags" : [ "Vendor Advisory" ]
}, {
"url" : "https://www.synology.com/security/advisory/Synology_SA_20_15",
"name" : "https://www.synology.com/security/advisory/Synology_SA_20_15",
"refsource" : "CONFIRM",
"tags" : [ "Third Party Advisory" ]
}, {
"url" : "https://support.lenovo.com/de/en/product_security/len-30041",
"name" : "https://support.lenovo.com/de/en/product_security/len-30041",
"refsource" : "MISC",
"tags" : [ ]
}, {
"url" : "https://security.netapp.com/advisory/ntap-20200611-0007/",
"name" : "https://security.netapp.com/advisory/ntap-20200611-0007/",
"refsource" : "CONFIRM",
"tags" : [ ]
}, {
"url" : "https://www.kb.cert.org/vuls/id/257161",
"name" : "VU#257161",
"refsource" : "CERT-VN",
"tags" : [ ]
} ]
},
"description" : {
"description_data" : [ {
"lang" : "en",
"value" : "Out-of-bounds read in IPv6 subsystem in Intel(R) AMT and Intel(R) ISM versions before 14.0.33 may allow an unauthenticated user to potentially enable denial of service via network access."
} ]
}
},
"configurations" : {
"CVE_data_version" : "4.0",
"nodes" : [ {
"operator" : "OR",
"children" : [ ],
"cpe_match" : [ {
"vulnerable" : true,
"cpe23Uri" : "cpe:2.3:a:intel:active_management_technology:*:*:*:*:*:*:*:*",
"versionStartIncluding" : "11.0",
"versionEndIncluding" : "11.8.76",
"cpe_name" : [ ]
}, {
"vulnerable" : true,
"cpe23Uri" : "cpe:2.3:a:intel:active_management_technology:*:*:*:*:*:*:*:*",
"versionStartIncluding" : "11.10",
"versionEndIncluding" : "11.11.76",
"cpe_name" : [ ]
}, {
"vulnerable" : true,
"cpe23Uri" : "cpe:2.3:a:intel:active_management_technology:*:*:*:*:*:*:*:*",
"versionStartIncluding" : "11.20",
"versionEndIncluding" : "11.22.76",
"cpe_name" : [ ]
}, {
"vulnerable" : true,
"cpe23Uri" : "cpe:2.3:a:intel:active_management_technology:*:*:*:*:*:*:*:*",
"versionStartIncluding" : "12.0",
"versionEndIncluding" : "12.0.63",
"cpe_name" : [ ]
}, {
"vulnerable" : true,
"cpe23Uri" : "cpe:2.3:a:intel:active_management_technology:*:*:*:*:*:*:*:*",
"versionStartIncluding" : "13.0",
"versionEndIncluding" : "13.0.31",
"cpe_name" : [ ]
}, {
"vulnerable" : true,
"cpe23Uri" : "cpe:2.3:a:intel:active_management_technology:*:*:*:*:*:*:*:*",
"versionStartIncluding" : "14.0",
"versionEndIncluding" : "14.0.32",
"cpe_name" : [ ]
}, {
"vulnerable" : true,
"cpe23Uri" : "cpe:2.3:a:intel:software_manager:*:*:*:*:*:*:*:*",
"versionStartIncluding" : "11.0",
"versionEndIncluding" : "11.8.76",
"cpe_name" : [ ]
}, {
"vulnerable" : true,
"cpe23Uri" : "cpe:2.3:a:intel:software_manager:*:*:*:*:*:*:*:*",
"versionStartIncluding" : "11.10",
"versionEndIncluding" : "11.11.76",
"cpe_name" : [ ]
}, {
"vulnerable" : true,
"cpe23Uri" : "cpe:2.3:a:intel:software_manager:*:*:*:*:*:*:*:*",
"versionStartIncluding" : "11.20",
"versionEndIncluding" : "11.22.76",
"cpe_name" : [ ]
}, {
"vulnerable" : true,
"cpe23Uri" : "cpe:2.3:a:intel:software_manager:*:*:*:*:*:*:*:*",
"versionStartIncluding" : "12.0",
"versionEndIncluding" : "12.0.63",
"cpe_name" : [ ]
}, {
"vulnerable" : true,
"cpe23Uri" : "cpe:2.3:a:intel:software_manager:*:*:*:*:*:*:*:*",
"versionStartIncluding" : "13.0",
"versionEndIncluding" : "13.0.31",
"cpe_name" : [ ]
}, {
"vulnerable" : true,
"cpe23Uri" : "cpe:2.3:a:intel:software_manager:*:*:*:*:*:*:*:*",
"versionStartIncluding" : "14.0",
"versionEndIncluding" : "14.0.32",
"cpe_name" : [ ]
} ]
} ]
},
"impact" : {
"baseMetricV3" : {
"cvssV3" : {
"version" : "3.1",
"vectorString" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"attackVector" : "NETWORK",
"attackComplexity" : "LOW",
"privilegesRequired" : "NONE",
"userInteraction" : "NONE",
"scope" : "UNCHANGED",
"confidentialityImpact" : "NONE",
"integrityImpact" : "NONE",
"availabilityImpact" : "HIGH",
"baseScore" : 7.5,
"baseSeverity" : "HIGH"
},
"exploitabilityScore" : 3.9,
"impactScore" : 3.6
},
"baseMetricV2" : {
"cvssV2" : {
"version" : "2.0",
"vectorString" : "AV:N/AC:L/Au:N/C:N/I:N/A:P",
"accessVector" : "NETWORK",
"accessComplexity" : "LOW",
"authentication" : "NONE",
"confidentialityImpact" : "NONE",
"integrityImpact" : "NONE",
"availabilityImpact" : "PARTIAL",
"baseScore" : 5.0
},
"severity" : "MEDIUM",
"exploitabilityScore" : 10.0,
"impactScore" : 2.9,
"acInsufInfo" : false,
"obtainAllPrivilege" : false,
"obtainUserPrivilege" : false,
"obtainOtherPrivilege" : false,
"userInteractionRequired" : false
}
},
"publishedDate" : "2020-06-15T14:15Z",
"lastModifiedDate" : "2021-03-18T13:15Z"
}, {
"cve" : {[...]
I need to get the following values from the schema if the ID value is CVE-2020-0597:
CWE-125
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
7.5
I've never worked with this, so it's a little hard for me to understand how to do it in this structure. Can somebody show me an example for my case?
Without further details wrt conditions, array indices etc, I guess this is what you want:
jq -r '
.CVE_Items[] | select(.cve.CVE_data_meta.ID == "CVE-2020-0597")
| .cve.problemtype.problemtype_data[0].description[0].value,
(.impact.baseMetricV3.cvssV3 | .vectorString, .baseScore)
'
CWE-125
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
7.5
Demo

Firebase rules, how to allow users to only see their own data

I am trying to get a rule set working to allow users to see there own data...
My current rule set is:
{
"rules": {
".read": "root.child('users').child(auth.uid).child('admin').val() === true",
".write": "root.child('users').child(auth.uid).child('admin').val() === true",
"users": {
".indexOn": ["active"],
"$user_id": {
".read": "$user_id === auth.uid",
".write": "$user_id === auth.uid"
}
},
"active_alerts": {
".indexOn": "alert_id"
},
"trips": {
".indexOn": "archive",
"$trip_id": {
".read": "data.child('who_called').child('key').val() === root.child('users').child(auth.uid).child('customer').child('key').val()",
"notes": {
"$note_id": {
".read": "data.child('display').val() === true"
}
}
}
}
}
}
The user path has data that looks like this:
{
"active" : true,
"admin" : false,
"customer" : {
"key" : "-Ldsu71CgIJxh1DVTTCP",
"name" : "Demo Customer"
},
"email" : "emai#email.com",
"last_login" : "2019-05-02T18:34:26.466Z",
"name" : "Demo",
"primary_phone" : "4197460180",
"typeahead" : "demo"
}
and the matching item in /trips:
{
"airline" : {
"key" : "195",
"name" : "AAL"
},
"archive" : false,
"arrival_airport" : {
"code" : "PHL",
"icao" : "KPHL",
"key" : "108",
"name" : "Philadelphia",
"timezone" : "America/New_York"
},
"bill_to" : {
"key" : "-LdqFpqAOm-dOl9xBtp2",
"name" : "AGT Global Logistics "
},
"consignee" : {
"key" : "-LdqHNMzPrP9epp_W-DS",
"name" : "Exelon Peach Bottom"
},
"customer_reference" : "124914",
"departure_airport" : {
"code" : "MKE",
"icao" : "KMKE",
"key" : "90",
"name" : "Milwaukee",
"timezone" : "America/Chicago"
},
"last_update" : "2019-05-02T18:02:57.274Z",
"level" : {
"key" : "-LWlODaCFUcejExn41Rr",
"name" : "Next Flight Out"
},
"milestones" : [ {
"airport" : {
"code" : "MKE",
"icao" : "KMKE",
"key" : "90",
"name" : "Milwaukee",
"timezone" : "America/Chicago"
},
"flight_time" : "2019-05-02T12:33:00.000Z",
"status" : {
"key" : "4",
"name" : "completed"
},
"type" : {
"key" : "0",
"name" : "Picked up"
}
}, {
"airport" : {
"code" : "MKE",
"icao" : "KMKE",
"key" : "90",
"name" : "Milwaukee",
"timezone" : "America/Chicago"
},
"flight_time" : "2019-05-02T13:51:00.000Z",
"status" : {
"key" : "4",
"name" : "completed"
},
"type" : {
"key" : "1",
"name" : "Dropped to departure airport"
}
}, {
"airline" : {
"key" : "195",
"name" : "AAL"
},
"airport" : {
"code" : "MKE",
"icao" : "KMKE",
"key" : "90",
"name" : "Milwaukee",
"timezone" : "America/Chicago"
},
"alert_id" : 29624287,
"flight_number" : "4883",
"flight_time" : "2019-05-02T16:28:03.000Z",
"ident" : "PDT4883-1556601968-airline-0144",
"img_url" : "....",
"note" : "arrival ~ PDT4883 arrived at PHL from MKE",
"status" : {
"key" : "4",
"name" : "completed"
},
"type" : {
"key" : "2",
"name" : "Departed Airport"
}
}, {
"airline" : {
"key" : "195",
"name" : "AAL"
},
"airport" : {
"code" : "PHL",
"icao" : "KPHL",
"key" : "108",
"name" : "Philadelphia",
"timezone" : "America/New_York"
},
"alert_id" : 29624287,
"flight_number" : "4883",
"flight_time" : "2019-05-02T18:02:00.000Z",
"note" : "arrival ~ PDT4883 arrived at PHL from MKE",
"status" : {
"key" : "4",
"name" : "completed"
},
"type" : {
"key" : "4",
"name" : "Arrived Airport"
}
}, {
"airport" : {
"code" : "PHL",
"icao" : "KPHL",
"key" : "108",
"name" : "Philadelphia",
"timezone" : "America/New_York"
},
"flight_time" : "2019-05-02T20:00:00.000Z",
"status" : {
"key" : 0,
"name" : "planned"
},
"type" : {
"key" : "6",
"name" : "Out for delivery"
}
}, {
"airport" : {
"code" : "PHL",
"icao" : "KPHL",
"key" : "108",
"name" : "Philadelphia",
"timezone" : "America/New_York"
},
"flight_time" : "2019-05-02T21:30:00.000Z",
"status" : {
"key" : 0,
"name" : "planned"
},
"type" : {
"key" : "7",
"name" : "Delivered"
}
} ],
"pieces" : [ {
"description" : "Valves",
"height" : "11",
"length" : "27",
"qty" : "1",
"units" : {
"key" : "2",
"name" : "IN"
},
"weight" : "50",
"weight_units" : {
"key" : "3",
"name" : "LBS"
},
"width" : "19"
} ],
"protect_time" : "2019-05-02T21:30:00.000Z",
"ready_time" : "2019-05-02T13:00:00.000Z",
"shipper" : {
"key" : "-LdqG3I48m662R7ABa5i",
"name" : "FAIRBANKS MORSE - MKE"
},
"trip_id" : "LFC-155676269",
"trip_notes" : [ {
"date_time" : "2019-05-02T10:29:43.892Z",
"display" : true,
"note" : "delay ~ Philadelphia Intl (PHL) is experiencing all inbound flights being held at their origin due to low clouds"
}, {
"date_time" : "2019-05-02T13:05:52.708Z",
"display" : true,
"note" : "filed ~ PDT4883 (E145) filed to depart MKE # Thu (02 May) 16:24 GMT for PHL # ETA 18:09 GMT (02 May) (UECKR5 SAMPL ADIME GERBS J146 CXR EWC JST BOJID2)"
}, {
"date_time" : "2019-05-02T14:51:00.000Z",
"display" : true,
"note" : "Shipment has been manifested onto flight AA4883 - TC"
}, {
"date_time" : "2019-05-02T16:28:31.325Z",
"display" : true,
"note" : "departure ~ PDT4883 (E145) departed MKE # 16:28 GMT for PHL ETA 18:13 GMT"
}, {
"date_time" : "2019-05-02T18:02:57.274Z",
"display" : true,
"note" : "arrival ~ PDT4883 arrived at PHL from MKE"
} ],
"who_called" : {
"key" : "-Ldsu71CgIJxh1DVTTCP",
"name" : "Demo Customer"
}
}
as you can see, the customer.key and who_called key match, but the user is still not able to see the data. Not sure what I am doing wrong here in the whole rule set. Your help is appreciated!
To allow users see trips added by them use the query-based rules like this;
"trips": {
".indexOn": "archive",
".read": "auth.uid != null && query.orderByChild == 'who_called/key' &&
query.equalTo == root.child('users/' + auth.uid + '/customer/key').val()",
"$trip_id": {
".read": "data.child('who_called').child('key').val() === root.child('users').child(auth.uid).child('customer').child('key').val()",
"notes": {
"$note_id": {
".read": "data.child('display').val() === true"
}
}
}
}
Only restriction with this is you cannot access the user's trips without using the query specified in the rule. That means you can't access the trips like this;
firebase.database().ref('users/USERID/customer/-Ldsu71CgIJxh1DVTTCP)
It has to be done like
firebase.database().ref('trips').orderByChild('who_called/key')
.equalTo('-Ldsu71CgIJxh1DVTTCP')
I've tried it and it works. Hope it helps

Firebase retrievals using orderbyvalue

I'm trying to retrieve the names of the students under a particular city like say Delhi 1. The code works when the city is explicitly specified but doesn't when the city is a user specific variable.
json-
{
"Schedule" : {
"Delhi 1 " : {
"22" : {
"6" : {
"2017" : "9:00"
}
}
},
"Delhi 2 " : {
"12" : {
"6" : {
"2017" : "5 pm"
}
}
},
"Delhi 3 " : {
"1" : {
"6" : {
"2017" : "10 am"
}
},
"10" : {
"6" : {
"2017" : "11 am"
}
}
}
},
"Students" : {
"Delhi_1" : {
"s1345" : {
"level" : "story",
"name" : "s1345"
},
"s454" : {
"level" : "paragraph",
"name" : "s454"
}
},
"Delhi_2" : {
"abc12" : {
"level" : "story",
"name" : "abc12"
},
"bh45" : {
"level" : "paragraph",
"name" : "bh45"
}
},
"Delhi_3" : {
"ca12" : {
"level" : "story",
"name" : "ca12"
},
"cv23" : {
"level" : "book",
"name" : "cv23"
}
},
"Delhi_4" : {
"bv43" : {
"level" : "story",
"name" : "bv43"
},
"gf43" : {
"level" : "story",
"name" : "cf43"
}
}
},
"Volunteers" : {
"Delhi 1 " : {
"abcd4" : {
"attendance" : 0,
"center" : "Delhi 1 ",
"email" : "a#mail.com",
"phone" : "45878704",
"v_name" : "abcd4"
},
"df3" : {
"attendance" : 0,
"center" : "Delhi 1 ",
"email" : "d#mail.com",
"phone" : "58564543",
"v_name" : "df3"
}
},
"Delhi 2 " : {
"df4" : {
"attendance" : 0,
"center" : "Delhi 2 ",
"email" : "d#mail.com",
"phone" : "48745421212",
"v_name" : "df4"
}
},
"vabc1" : {
"attendance" : 0,
"center" : "Delhi 1 ",
"email" : "s#mail.com",
"phone" : "3799623472",
"v_name" : "vabc1"
}
}
}
Code-
myRef=database.child(center);
myRef.orderByValue().addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot child: dataSnapshot.getChildren()) {
for(DataSnapshot child2: child.getChildren()) {
Stringvalue=child.child("name").getValue().toString();
value.setName(dataSnapshot.child("name").getValue().toString());
System.out.println("Values" + value);
}
}
}

Druid query does not return case Insensitive results for count aggregation

Ideally, I need to get the count of how many times "London" is used in the city name. But the query returns different values for "london" and "London" and "LoNdOn" and so on.
I have tried using Case Insensitive as an option, but it doesn't give me the required result.
Here's my query,
{
"queryType": "topN",
"dataSource": "wikiticker",
"dimension":"cityName",
"granularity": "ALL",
"metric": "count",
"threshold": 10,
"filter":
{
"type": "search",
"dimension": "cityName",
"query": {
"type": "insensitive_contains",
"value": "london",
}
},
"aggregations": [
{
"type": "longSum",
"name": "count",
"fieldName": "count"
}
],
"intervals": ["2014-10-01T00:00:00.000Z/2016-10-07T00:00:00.000Z"]
}
And here's my result :
[ {
"timestamp" : "2015-09-12T00:46:58.771Z",
"result" : [ {
"count" : 21,
"cityName" : "London"
},
{
"count" : 10,
"cityName" : "New London"
},
{
"count" : 3,
"cityName" : "london"
},
{
"count" : 1,
"cityName" : "LoNdon"
},
{
"count" : 1,
"cityName" : "LondOn"
} ]
} ]
I should get something like:
[ {
"timestamp" : "2015-09-12T00:46:58.771Z",
"result" : [ {
"count" : 26,
"cityName" : "London"
},
{
"count" : 10,
"cityName" : "New London"
} ]
} ]
Use the filtered aggregator:
A filtered aggregator wraps any given aggregator, but only aggregates the values for which the given dimension filter matches.
{
"type" : "filtered",
"filter" : {
"type" : "search",
"dimension" : cityName,
"query": {
"type":"contains",
"value":"london"
}
},
"aggregator" : {
"type": "count",
"name": "Total Count of the Name London"
}
}
References
Druid Documentation: Filtered Aggregator

Mongolite and aggregation with $lookup on ObjectId vs character

Working with mongolite v0.9.1 (R) and MongoDB v3.4, I'd like to join two collections, the first one, the parent containing an ObjectId, the second one, the children containing the string value of the parents' ObjectId.
This is the basic syntax :
conParent$aggregate('[
{ "$lookup":
{ "from":"Children",
"localField": "_id",
"foreignField": "parent_id",
"as": "children"
}
}
]')
$lookup seems to take only field name, I've tried this, producing syntaxic errors :
.../...
"foreignField": "{'$oid':'parent_id'}"
.../...
So is there a way to deal with that ?
In the other way, I tried to save the parent's ObjectId in the children in ObjectId format with no luck (I still get a string in MongoDB) :
result <- transform(
computeFunction,
parent_id = sprintf('{"$oid":"%s"}',parent$"_id"))
resultCon <- conout$insert(as.data.frame(result))
Is it possible to store an Id as ObjectId in mongolite?
Note : I'm doing bulk inserts so I can't deal with JSON string manipulations.
Any idea ?
Edit:
Here is an example of the collections i am using :
The Parent collection :
{
"_id" : ObjectId("586f7e8b837abeabb778d2fd"),
"name" : "Root1",
"date" : "2017-01-01",
"value" : 1.0,
"value1" : 10.0,
"value2" : 100.0
},
{
"_id" : ObjectId("586f7ea4837abeabb778d30a"),
"name" : "Root1",
"date" : "2017-01-02",
"value" : 2.0,
"value1" : 20.0,
"value2" : 200.0
}
The Children collection :
{
"_id" : ObjectId("586f7edf837abeabb778d319"),
"name" : "Item1",
"value" : 1.1,
"date" : "2017-01-01",
"parent_id" : "586f7e8b837abeabb778d2fd"
}
{
"_id" : ObjectId("586f7efa837abeabb778d324"),
"name" : "Item2",
"value1" : 11.111111111,
"value2" : 12.222222222,
"date" : "2017-01-01",
"parent_id" : "586f7e8b837abeabb778d2fd"
}
{
"_id" : ObjectId("586f7f15837abeabb778d328"),
"name" : "Item1",
"value" : 2.2,
"date" : "2017-01-02",
"parent_id" : "586f7ea4837abeabb778d30a"
}
{
"_id" : ObjectId("586f7f2b837abeabb778d32e"),
"name" : "Item2",
"value1" : 21.111111111,
"value2" : 22.222222222,
"date" : "2017-01-02",
"parent_id" : "586f7ea4837abeabb778d30a"
}
Could you try :
"foreignField": "_id"
Starting from mongo's website example :
library(mongolite)
library(jsonlite)
a = '[{ "_id" : 1, "item" : 1, "price" : 12, "quantity" : 2 },
{ "_id" : 2, "item" : 2, "price" : 20, "quantity" : 1 },
{ "_id" : 3 }]'
b= '[{ "_id" : 1, "sku" : "abc", "description": "product 1", "instock" : 120 },
{ "_id" : 2, "sku" : "def", "description": "product 2", "instock" : 80 },
{ "_id" : 3, "sku" : "ijk", "description": "product 3", "instock" : 60 },
{ "_id" : 4, "sku" : "jkl", "description": "product 4", "instock" : 70 },
{ "_id" : 5, "sku": null, "description": "Incomplete" },
{ "_id" : 6 }]'
mongo_orders <- mongo(db = "mydb", collection = "orders")
mongo_orders$insert(fromJSON(a))
mongo_inventory <- mongo(db = "mydb", collection = "inventory")
mongo_inventory$insert(fromJSON(b))
df <- mongo_orders$aggregate('[
{
"$lookup":
{
"from": "inventory",
"localField": "item",
"foreignField": "_id",
"as": "inventory_docs"
}
}
]')
str(df)
It works as well when both are set to _id
"localField": "_id",
"foreignField": "_id",
Well I must say that's not possible at all !
Mongilite retrieve _id as character and do not contain any ObjectId implementation.
So...

Resources