mongodb shell to java driver aggregate statement - driver

I'm able to run an aggregate MongoDb (3.8) request in the mongo shell but I can't get it out working using the java driver (3.4 java 8).
here's the input source structure. I want to aggregate informations to provide company activities stats. note that the ape document states for the company registered activity. I want to group on the first 3 digits of the ape code
{
"_id" : "00552017600016",
"sirene" : "005520176",
"nic" : "00016",
"natureCode" : "5710",
"natureLabel" : "SAS, société par actions simplifiée",
"name" : "HERNAS CARTONNAGE",
"brand" : "",
"registerDate" : ISODate("1954-12-31T23:00:00Z"),
"startDate" : ISODate("1954-12-31T23:00:00Z"),
"headquaters" : true,
"address" : {
"number" : 50,
"ext" : null,
"lane" : "RUE PASTEUR",
"zipcode" : "80210",
"city" : "FEUQUIERES EN VIMEU",
"country" : "FRANCE",
"location" : {
"type" : "Point",
"coordinates" : [
1.60319694244078,
50.0537636973407
],
"accuracy" : 0,
"ban" : "ADRNIVX_0000000260779642"
}
},
"ape" : {
"code" : "1721A",
"label" : "Fabrication de carton ondulé"
},
"staff" : {
"count" : 50,
"year" : 2016
}
}
running this commands in the shell works like a charm
db.companies_geo.aggregate([ {$match:{"address.city":"LE MANS"}},
{$group:{_id:{$substrBytes:["$ape.code",0,2]}, count:{$sum:1}, code:{$last:"$ape.code"}, label:{$last:"$ape.label"}}},
{$project:{count:1, code:1, label:1}},
{$sort:{count:-1}},
{$limit:20}
])
it produces this result
{ "_id" : "68", "count" : 4603, "code" : "6832B", "label" : "Supports juridiques de gestion de patrimoine immobilier" }
{ "_id" : "47", "count" : 1929, "code" : "4799B", "label" : "Vente par automate, aut. com. dét. hors mag., éventaire ou marché" }
{ "_id" : "94", "count" : 1874, "code" : "9499Z", "label" : "Autres organisations fonctionnant par adhésion volontaire" }
{ "_id" : "86", "count" : 1704, "code" : "8690F", "label" : "Activités de santé humaine non classées ailleurs" }
{ "_id" : "56", "count" : 832, "code" : "5630Z", "label" : "Débits de boissons" }
{ "_id" : "90", "count" : 816, "code" : "9004Z", "label" : "Gestion de salles de spectacles" }
{ "_id" : "85", "count" : 769, "code" : "8560Z", "label" : "Activités de soutien à l'enseignement" }
{ "_id" : "70", "count" : 592, "code" : "7022Z", "label" : "Conseil pour les affaires et autres conseils de gestion" }
{ "_id" : "96", "count" : 585, "code" : "9609Z", "label" : "Autres services personnels n.c.a." }
{ "_id" : "81", "count" : 582, "code" : "8130Z", "label" : "Services d'aménagement paysager" }
on the java side I've tried this but the code line bellow the while iteration raises the exception org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.mongodb.client.model.BsonField.
private List<Document> cityActivityGraph() {
Bson filter = Filters.eq("address.city", "LE MANS");
BsonField id = new BsonField("_id", Filters.eq(new Document("$substrBytes", Arrays.asList("$ape.code", 0, 2))));
BsonField count = Accumulators.sum("count", 1);
BsonField label = Accumulators.last("ape.label", 1);
BsonField code = Accumulators.last("ape.code", 1);
Bson group = Aggregates.group(id, count, code, label);
Bson match = Aggregates.match(filter);
Bson projections = Projections.include("code", "label", "count");
Bson project = Aggregates.project(projections);
Bson sort = Sorts.descending("count");
MongoCursor<Document> cursor = getTable().aggregate(Arrays.asList(
Aggregates.match(match),
Aggregates.group(group),
Aggregates.project(project),
Aggregates.sort(sort))).iterator(); <--- exception here
List<Document> result = new ArrayList<>();
while (cursor.hasNext()) {
Document doc = cursor.next();
System.out.println(doc.toJson());
result.add(doc);
}
return result;
}
any idea ? thanks in advance

found a solution, perhaps not the most efficient but it works
Bson id = new Document("_id", new Document("$substrBytes", Arrays.asList("$ape.code", 0, 3)));
BsonField code = Accumulators.last("code", "$ape.code");
BsonField label = Accumulators.last("label", "$ape.label");
BsonField count = Accumulators.sum("count", 1);
Bson projections = Projections.include("code", "label", "count");
Bson sort = Sorts.descending("count");
AggregateIterable<Document> stats = getTable().aggregate(Arrays.asList(
Aggregates.match(filter),
Aggregates.group(id, code, label, count),
Aggregates.project(projections),
Aggregates.limit(limit),
Aggregates.sort(sort)
));
List<Document> result = new ArrayList<>();
for (Document d:stats) {
result.add(d);
}
return result;

Related

firebase database filtering is not working. Need some assistance

I have a simple test database that I cant get to filter. I indexed the category in the rules:
"questions":{
".indexOn": ["category"]
},
My filter for the quiz app:
/questions.json?orderBy="category"&equalTo="Basics"&print=pretty
and my database:
"-MKoucSP33zm4jC43AnY" : {
"title" : {
"answers" : [ {
"score" : 30,
"text" : "Pineapple"
}, {
"score" : 5,
"text" : "Ham"
}, {
"score" : 20,
"text" : "Yogurt"
}, {
"score" : 10,
"text" : "Crab"
} ],
"category" : "Basics",
"questionId" : "101",
"questionImage" : "",
"questionLink" : "",
"questionText" : "What topping do you like the best on pizza?"
}
}
The category property is nested under the title node, so the property you need to order/filter on is title/category:
/questions.json?orderBy="title/category"&equalTo="Basics"&print=pretty
You'll also need to update your index definition for that path, so:
"questions": { ".indexOn": "title/category" }
Working example: https://stackoverflow.firebaseio.com/64596200/questions.json?orderBy="title/category"&equalTo="Basics"

Ignoring Firebase child

How could I query this data in this way:
I would like to ignore the CurrentSubAdministrativeArea child and iterate every each sub child and find the right userKey
Actually I'm using this code, that isnt working:
self.ref.child("Ads").child("CurrentSubAdministrativeArea")
/*HERE I would like to ignore the childs*/
.queryOrdered(byChild: "userKey").queryEqual(toValue: uid).observeSingleEvent(of:.value, with: { (snapshot) in
--
{
"Ads" : {
"CurrentSubAdministrativeArea" : {
"Mantova" : {
"-L7ymBmmbHkNfhBRte9F" : {
"cost" : 200,
"date" : 1527256922000,
"info" : "Test",
"maxLimit" : 100,
"minLimit" : 10,
"personBadType" : [ "abitudinaria", "antipatica" ],
"personGoodType" : [ "simpatica", "felice" ],
"subAdministrativeArea" : "Mantova",
"title" : "Mantova Test",
"url" : "https://firebasestorage.googleapis.com/v0/b/team-34540.appspot.com/o/Mantova%20Test?alt=media&token=3a81ed1c-ecd6-4dc0-bd7c-45e093ce8188",
"userKey" : "OsJRc98sqxPx70iqxFtoqerMzHH2",
"via" : "viale dei test"
}
},
"Milano" : {
"-L6qywMC6nxi0fJNMHba" : {
"cost" : 454,
"date" : 1528298580000,
"info" : "Di pollo",
"maxLimit" : 100,
"minLimit" : 10,
"personBadType" : [ "abitudinaria", "antipatica" ],
"personGoodType" : [ "simpatica", "felice" ],
"subAdministrativeArea" : "Milano",
"title" : "Pollo 2",
"url" : "https://firebasestorage.googleapis.com/v0/b/team-34540.appspot.com/o/Pollo?alt=media&token=fc6a3ec8-5f9a-4347-bdad-2d9715af784d",
"userKey" : "OsJRc98sqxPx70iqxFtoqerMzHH2",
"via" : "viale test"
}
}
}
}
}
You could denormalize your data in such a way your query is easy to build and execute.
Together with the data structure you already have you would have another node (ie. another data structure) like
{
"AdsByUsers" : {
"OsJRc98sqxPx70iqxFtoqerMzHH2": {
"Mantova",
"Milano",
...
},
"abcde88qxPx70iqxFtoqerMzKh5": {
"Firenze",
...
}
With NoSQL database you should not hesitate to duplicate data in such a way your queries are easy and fast to execute.

Is it possible to create Salesreceipt without product/service value through QBO API?

Is it possible to create Salesreceipt without product/service value through QBO API? I have tried through API but it's not reflecting rate value and storing description value only.
If I remove ItemRef attribute(in request body) then it's reflecting rate and amount values and it's assigning some default and random product/service.
It is possible directly in QBO UI.
Request body where only description value storing:
{
"TxnDate" : "2016-05-27",
"Line" : [ {
"Amount" : 2222.00,
"Description" : "hi chk",
"DetailType" : "ItemReceiptLineDetail",
"ItemReceiptLineDetail" : {
"ItemRef" : { },
"Qty" : 1,
"UnitPrice" : 2222
} }
],
"CustomerRef" : {
"value" : "67"
},
"CustomerMemo" : {
"value" : "Thanks for your business! We appreciate referrals!"
},
"TotalAmt": 2222.00,
"PrivateNote" : "",
"CustomField" : [ {
"DefinitionId" : "1",
"Type" : "StringType",
"StringValue" : ""
} ]
}
Request body where default product/service assigning:
{
"TxnDate" : "2016-05-27",
"Line" : [ {
"Amount" : 2222.00,
"Description" : "hi chk",
"DetailType" : "ItemReceiptLineDetail",
"ItemReceiptLineDetail" : {
"Qty" : 1,
"UnitPrice" : 2222
} }
],
"CustomerRef" : {
"value" : "67"
},
"CustomerMemo" : {
"value" : "Thanks for your business! We appreciate referrals!"
},
"TotalAmt": 2222.00,
"PrivateNote" : "",
"CustomField" : [ {
"DefinitionId" : "1",
"Type" : "StringType",
"StringValue" : ""
} ]
}
No.
QuickBooks Online does not support this.

SwiftyJSON array empty

I want to retrieve data from a JSON file with SwiftyJSON and Alamofire. This is the JSON data:
json: {
"data" : {
"monitors" : [
{
"lines" : [
{
"towards" : "LEOPOLDAU",
"realtimeSupported" : true,
"departures" : {
"departure" : [
{
"departureTime" : {
"countdown" : 2,
"timePlanned" : "2015-09-09T18:47:03.000+0200",
"timeReal" : "2015-09-09T18:47:03.000+0200"
}
},
{
"departureTime" : {
"countdown" : 6,
"timePlanned" : "2015-09-09T18:51:03.000+0200",
"timeReal" : "2015-09-09T18:51:03.000+0200"
}
}
]
},
"lineId" : 301,
"platform" : "1",
"trafficjam" : false,
"richtungsId" : "1",
"direction" : "H",
"type" : "ptMetro",
"name" : "U1",
"barrierFree" : true
}
],
"attributes" : {
},
"locationStop" : {
"type" : "Feature",
"geometry" : {
"type" : "Point",
"coordinates" : [
16.4330680046932,
48.2430825589716
]
},
"properties" : {
"municipality" : "Wien",
"title" : "Kagran",
"coordName" : "WGS84",
"municipalityId" : 90000,
"type" : "stop",
"gate" : "1",
"name" : "60200627",
"attributes" : {
"rbl" : 4127
}
}
}
}
]
}
,
"message" : {
"value" : "OK",
"serverTime" : "2015-09-09T18:45:08.998+0200",
"messageCode" : 1
}
}
What I want to do now is get the data of lines into an array. I tried several combinations for that, e.g.
let departureArray = jsonData["data"]["monitors"][0]["lines"][0].array
or
let departureArray = jsonData["data"]["monitors"]["lines"].array
but my array is always empty. Does anyone has an idea how to do this properly?
Your expected array departureArray is in fact a dictionary
let departureDictionary = jsonData["data"]["monitors"][0]["lines"][0].dictionary

Why my PassBook isn't valid or outdate?

I generate one passbook using this gem in rails and it seen that works but when I open the passbook .pkpass file I see this message:
It's in spanish but basically it says that this card isn't valid anymore.
Here is my JSON:
{
"formatVersion" : 1,
"passTypeIdentifier" : "{MY PASS ID HERE}",
"serialNumber" : "E5982H-I2",
"teamIdentifier" : "{MY TEAM ID HERE}",
"webServiceURL" : "https://example.com/passes/",
"authenticationToken" : "vxwxd7J8AlNNFPS8k0a0FfUFtq0ewzFdc",
"barcode" : {
"message" : "123456789",
"format" : "PKBarcodeFormatPDF417",
"messageEncoding" : "iso-8859-1"
},
"locations" : [
{
"longitude" : -122.3748889,
"latitude" : 37.6189722
},
{
"longitude" : -122.03118,
"latitude" : 37.33182
}
],
"organizationName" : "CROCANTICKETS SL",
"description" : "Paw Planet Coupon",
"logoText" : "Paw Planet",
"foregroundColor" : "rgb(255, 255, 255)",
"backgroundColor" : "#FF4B33",
"coupon" : {
"primaryFields" : [
{
"key" : "offer",
"label" : "Any premium dog food",
"value" : "20% off"
}
],
"auxiliaryFields" : [
{
"key" : "expires",
"label" : "EXPIRES",
"value" : "2016-04-24T10:00-05:00",
"isRelative" : true,
"dateStyle" : "PKDateStyleShort"
}
]
}
}
Any idea? Thanks!
According to the Expiration Keys in the Passbook Package Format Reference check the expirationDate and voided keys. Since you do not have those in your JSON, it might be added by the gem you are using.

Resources