Group by multiple fields and get max value using Dart and Flutter - flutter

I am new to dart, I have a requirement to group by multiple fields and get the minimum value of each student. I don't have an idea on how to implement since I am new in dart. Below is the example of the realtime firebase table structure.
"gameRanking" : {
"-MmvcDgrGsuCjhcsmXfP" : {
"game" : "Puzzle",
"score" : "105",
"student" : "John Doe",
},
"-MasdDgrGsuCjhcsmXfP" : {
"game" : "Puzzle",
"score" : "99",
"student" : "John Doe",
},
"-Mmw0kagqLrEbdWlkXg7" : {
"game" : "Puzzle",
"score" : "87",
"student" : "Mary Doe",
},
"-MmwC8ONbJUWzP_Wa7X0" : {
"game" : "Puzzle",
"score" : "95",
"student" : "Mary Doe",
}
},
Here is the expected output:
Puzzle John Doe 99
Puzzle Mary Doe 87

I won't answer the question entirely because it's clearly a "do my homework" kind of question.
But in order to assist you in getting started with programming, I thought it would be useful to post "nearly" the whole solution here. I hope you will be able to then read answers in other related questions, for example this one, to get to the final solution.
Here you go, this solves the "plumbing" part of the problem:
class Stats {
String game;
int score;
String student;
Stats(this.game, this.score, this.student);
#override
String toString() => "Stats($game, $score, $student)";
}
main() {
final map = {
"gameRanking": {
"-MmvcDgrGsuCjhcsmXfP": {
"game": "Puzzle",
"score": "105",
"student": "John Doe",
},
"-MasdDgrGsuCjhcsmXfP": {
"game": "Puzzle",
"score": "99",
"student": "John Doe",
},
"-Mmw0kagqLrEbdWlkXg7": {
"game": "Puzzle",
"score": "87",
"student": "Mary Doe",
},
"-MmwC8ONbJUWzP_Wa7X0": {
"game": "Puzzle",
"score": "95",
"student": "Mary Doe",
}
},
};
final rankingsById = map["gameRanking"] ?? {};
final rankings = rankingsById.map((id, data) {
return MapEntry(
id,
Stats(data["game"].coerceToString(), data["score"].coerceToInt(),
data["student"].coerceToString()));
}).values;
rankings.forEach((stats) => print(stats));
}
extension on Object? {
int coerceToInt() => int.parse(coerceToString());
String coerceToString() => this?.toString() ?? "?";
}
Running this prints:
Stats(Puzzle, 105, John Doe)
Stats(Puzzle, 99, John Doe)
Stats(Puzzle, 87, Mary Doe)
Stats(Puzzle, 95, Mary Doe)
Good luck finishing the rest of the owl :)

I needed the same... I don't know if this is the best solution...
Map<int,List<MyObject>> mom=groupBy(_myObjectList,(element)=>element.cornerCnt);//get a Map with cornerCnt as key and a List of myObjects for every key
int maxCornerCnt;
int max=0;
mom.forEach((key, moList) { //for every map entry
int len=moList.length; //get lenght of myObject-list
if (len>max) {
max=len;
maxCornerCnt=key; //write key(cornerCnt) to maxCornerCnt
}
});

Related

MongoDB text search string equality?

I'm new to MongoDB and was looking through the docs a few nights ago and saw something that I haven't been able to locate since...
There was an option, I believe it was related to $text search, to treat an array of strings as if they were the same word. The syntax looked something like this:
["cheez", "cheese"],
["donut", "doughnut"],
["chips", "fries", "crisps"],
So a search for "chips" would return all documents indexed with "fries" or "crisps" even if they did not also have "chips".
Please tell me I wasn't dreaming!
YOU ARE NOT DREAMING
mongodb fuzzy text search
The following query searches the title field for the phrase naw yark. It uses the fuzzy default options where:
maxEdits allows up to two character variation of each term in the
given phrase to match the query to a document.
maxExpansions considers up to fifty similar terms for each term in
naw yark to find matches.
prefixLength is disabled.
The query also includes a $limit stage to limit the output to 10 results and a $project stage to:
Exclude all fields except title
Add a field named score
db.movies.aggregate([
{
$search: {
"text": {
"path": "title",
"query": "naw yark",
"fuzzy": {}
}
}
},
{
$limit: 10
},
{
$project: {
"_id": 0,
"title": 1,
score: { $meta: "searchScore" }
}
}
])
The above query returns the following results:
{ "title" : "New York, New York", "score" : 4.392756462097168 }
{ "title" : "New York", "score" : 4.050914287567139 }
{ "title" : "New York Stories", "score" : 3.4838104248046875 }
{ "title" : "New York Minute", "score" : 3.4838104248046875 }
{ "title" : "Synecdoche, New York", "score" : 3.4838104248046875 }
{ "title" : "New York Doll", "score" : 3.4838104248046875 }
{ "title" : "Little New York", "score" : 3.4838104248046875 }
{ "title" : "Escape from New York", "score" : 3.0559897422790527 }
{ "title" : "King of New York", "score" : 3.0559897422790527 }
{ "title" : "Naked in New York", "score" : 3.0559897422790527 }
also synonyms:
mongodb synonyms text search

MongoDB query for a specific field within a document returns empty document

For each GSM subscriber, I have a document in "Service" collection and the part I'm querying is as below (Had to omit parts of the document and divide it into two sections since it was quite long), I'm trying to to fetch documentVerifiedDate where documentPurpose and serviceNumber are equal to specific values:
{
"_id": ObjectId("59abee12e4b044ce2d6001b6"),
"service": {
"serviceRequestId": "1335102",
"serviceIndex": "S0",
"accountIndex": "A0",
"serviceUser": {
"isServiceUserSameAsCustomer": "Y",
"isHolder": "N",
"isPayer": "N",
"profileDetails": {
"identificationDetails": {
"identificationDetail": [{
"idType": {
"masterCode": "PASS"
},
"documentPurpose": {
"masterCode": "POID"
},
"idNumber": "9339904299",
"isReceived": "Y",
"isVerified": "Y",
"documentReceivedDate": ISODate("2017-09-05T08:13:25.000+0000"),
"DMSReferenceNo": "85449499",
"documentVerifiedDate": ISODate("2017-09-05T08:13:25.000+0000")
},
{
"idType": {
"masterCode": "REGFORM"
},
"documentPurpose": {
"masterCode": "REGFORM"
},
"isUploaded": "Y",
"isReceived": "Y",
"isVerified": "Y",
"documentUploadedDate": ISODate("2017-09-05T08:13:25.000+0000"),
"DMSReferenceNo": "85449499",
"documentReceivedDate": ISODate("2017-09-05T08:13:25.000+0000"),
"documentVerifiedDate": ISODate("2017-09-05T08:13:25.000+0000")
},
{
"idType": {
"masterCode": "MMS"
},
"documentPurpose": {
"masterCode": "MMS"
},
"isUploaded": "Y",
"isReceived": "Y",
"isVerified": "Y",
"documentUploadedDate": ISODate("2017-09-05T08:13:25.000+0000"),
"DMSReferenceNo": "85449499",
"documentReceivedDate": ISODate("2017-09-05T08:13:25.000+0000"),
"documentVerifiedDate": ISODate("2017-09-05T08:13:25.000+0000")
}
]
},
and also:
"serviceDetails" : {
"serviceNumberCategory" : {
"masterCode" : "NORML"
},
"selfCareAccount" : "Y",
"contractDetails" : {
"startDate" : ISODate("2017-09-03T11:56:58.658+0000"),
"endDate" : ISODate("9999-12-31T00:00:00.000+0000")
},
"technology" : {
"masterCode" : "GSM"
},
"starterKitUpdated" : "Y",
"relatedProject" : "",
"businessType" : {
"masterCode" : "Prepaid"
},
"mobileMoneyAccount" : "Y",
"activatedVia" : {
"masterCode" : "SP"
},
"serviceType" : {
"masterCode" : "GSM"
},
"subServiceType" : {
"masterCode" : "Voice"
},
"serviceNumber" : "9339904299",
"simDetails" : {
I've written below query to fetch documentVerifiedDate where documentPurpose is POID and serviceNumber is 9339904299:
db.Service.find ({
"service.serviceDetails.serviceNumber": "9339902499",
"service.serviceUser.profileDetails.identificationDetails.identificationDetail.0.documentPurpose.masterCode" : "POID"
},
{
"service.serviceUsear.profileDetails.identificationDetails.identificationDetail.0.documentVerifiedDate" : 1,
_id: 0
})
and I'm getting below result:
{
"service" : {
}
}
I'd appreciate it if you could help me understand why above query does not serve the intended purpose, i.e. documentVerifiedDate is not returned.
I've used below link to write the query.
SQL to MongoDB Mapping Chart
From the docs,
$elemMatch, $slice, and $ are the only way to project specific
elements to include in the returned array. For instance, you cannot
project specific array elements using the array index; e.g. {
"instock.0": 1 } projection will not project the array with the first
element.
Use $ positional operator.
Something like
db.Service.find ({
"service.serviceDetails.serviceNumber": "9339904299",
"service.serviceUser.profileDetails.identificationDetails.identificationDetail.documentPurpose.masterCode": "POID"
},
{
"service.serviceUser.profileDetails.identificationDetails.identificationDetail.$": 1
})
This will give you the matching identificationDetail object and you can use the documentVerifiedDate from the document.
Note: serviceNumber in the query is not matching the provided document. I have adjusted query to use the serviceNumber from document.

Revel+mgo golang - How to define a struct type to handle nested objects coming from the db?

I have this kind of documents in my mongo collection -
{
"_id" : "3wPEpWwECbrTrnSbh",
"brandId" : 45,
"title" : "brandtitle",
"logoImg" : "brandtitle.png",
"category" : {
"category 1" : [
{
"cat" : "A1 Plus Champ"
},
{
"cat" : "A108"
},
{
"cat" : "A6"
},
],
"category 2" : [
{
"cat" : "something"
},
{
"cat" : "soemthing else"
},
{
"cat" : "something else"
},
],
},
"isActive" : true,
"isOnboarded" : false,
"serviceNumber" : 18605001492.0
}
So there are several brands.
I can get everything, except the category in this.
My Models code data type for this is -
type Brand struct {
Id string `bson:"_id" json:"_id"`
Brandid int `bson:"brandId" json:"brandId"`
Title string `json:"title"`
Logoimg string `bson:"logoImg" json:"logoImg"`
Category []string `bson:"category" json:"category"`
Isactive bool `bson:"isActive" json:"isActive"`
Isonboarded bool `bson:"isOnboarded" json:"isOnboarded"`
Servicenumber int `bson:"serviceNumber" json:"serviceNumber"`
}
I'm taking Category to be a string array right now but of course that's wrong.
The output looks like this -
{
"_id": "3wPEpWwECbrTrnSbh",
"brandId": 45,
"title": "brandtitle",
"logoImg": "brandtitle.png",
"category": null,
"isActive": true,
"isOnboarded": false,
"serviceNumber": 18605001492
}
How should I construct this struct to be able to display the kind of data I'm getting out from the database?
type Brand struct {
Id string `bson:"_id" json:"_id"`
Brandid int `bson:"brandId" json:"brandId"`
Title string `json:"title"`
Logoimg string `bson:"logoImg" json:"logoImg"`
Category map[string][]map[string]string `bson:"category" json:"category"`
Isactive bool `bson:"isActive" json:"isActive"`
Isonboarded bool `bson:"isOnboarded" json:"isOnboarded"`
Servicenumber int `bson:"serviceNumber" json:"serviceNumber"`
}

Increment nested value

I create players the following way.
Players.insert({
name: name,
score: 0,
items: [{'name': 0}, {'name2': 0}...]
});
How do I increment the score in a specific player and specific item name (upserting if necessary)?
Sorry for the terrible wording :p
Well, the answer is - as in life - to simplify the problem by breaking it up.
And to avoid arrays in mongoDB - after all, objects can have as many keys as you like. So, my structure became:
{
"_id": <id>,
"name": <name>,
"score": <score>,
"items": {}
}
And to increment the a dynamic key in items:
// create your update skeleton first
var ud = { $inc: {} };
// fill it in
ud.$inc['item.' + key] = value;
// call it
db.Players.update(player, ud, true);
Works a charm :)
Lets say you have:
{
"_id" : ObjectId("5465332e6c3e2eeb66ef3683"),
"name" : "Alex",
"score" : 0,
"items" : [
{
"food" : 0
}
]
}
To update you can do:
db.Players.update({name: "Alex", "items.food": {$exists : true}},
{$inc: {score: 1, "items.$.food": 5}})
Result:
{
"_id" : ObjectId("5465332e6c3e2eeb66ef3683"),
"name" : "Alex",
"score" : 1,
"items" : [
{
"food" : 5
}
]
}
I am not sure you can upsert if the document doesn't exist because of the positional operator needed to update the array.

Map Reduce by date with RockMongo admin panel

I am trying to find the best way to clean my Mongo DB from old rows. This is the row structure:
{
"_id": ObjectId("52adb7fb12e20f2e2400be38"),
"1": "2013-12-15 06: 07: 20",
"2": "1",
"3": "",
"4": "",
"5": "ID",
"6": "139.195.98.240",
"7": "",
"8": "youtube",
"9": NumberInt(0),
"10": "",
"11": ""
}
The date field is this.1. So I want to set a delte method for all rows older then 30 days.
So I figured out that a map can help with this task, if there are any other suggestion please feel free to suggest.
This is the map function that i am trying to run:
{
mapreduce : "delete_rows",
map : function () {
var delete_date = new Date();
delete_date.setDate(delete_date.getDate()-7);
row_date = new Date(this.1);
if(row_date < delete_date){
emit(this._id,{date: this.1}, {all_data: this});
}
},
out : {
"delete_rows"
},
keeptemp:false,
jsMode : false,
verbose : false
}
I get the following error at rockmongo query window:
Criteria must be a valid JSON object
Can anyone jelp me with this syntax?
Thanks