Firebase-Dart Filtering Data - firebase

My data is something like this:
{
"members": [
{
"type": "alpha",
"name": "John"
},
{
"type": "alpha",
"name": "Jane"
},
{
"type": "beta",
"name": "Renata"
},
{
"type": "beta",
"name": "Richard"
}
]
}
If I access it as follows, I get the list of all members:
DatabaseReference ref = database().ref('members')
ref.onValue.listen((e) {
var members = e.snapshot.val();
});
However, if I try to filter the data, as follows, I get null.
DatabaseReference ref = database().ref('members').orderByValue().equalTo("alpha", "type");
ref.onValue.listen((e) {
var members = e.snapshot.val();
});
How do I get only objects with "type" "alpha"?

Your members reference corresponds to a List of objects, and none of the immediate children in the List are strings like "alpha" so your orderByValue().equalTo() query returns null. The "type" argument you're passing is searching on indices in the list (0, 1, etc.) rather than keys in the child objects ("type", "name").
Instead, you can use orderByChild():
DatabaseReference ref = database().ref().child('members').orderByChild("type").equalTo("alpha");
You may find that you get a List with some holes in it, if the alphas aren't at the beginning:
[{name: John, type: alpha}, null, {name: Jane, type: alpha}]
You can remove the null values with
members = new List<Object>.from(members)..remove(null);

Related

How can I query Cosmos DB with ARRAY_CONTAINS using SqlParameters when the Array contains JSON Objects

Given the following query
SELECT * FROM root r WHERE ARRAY_CONTAINS(#types, r.Type)
I want to build a SQLQuerySpec like this
private SqlQuerySpec BuildQuery(IEnumerable<MyType> search)
{
var queryText = "SELECT * FROM root r WHERE ARRAY_CONTAINS(#types, r.Type)";
//What is the required <structure/Type> of the second
//parameter to the constructor of <SqlParameter>?
//so it becomes a JSON object/JSON Array
var param = new SqlParameter("#types", search.ToArray())
var parameters = new SqlParameterCollection{param};
return new SqlQuerySpec() {QueryText = queryText, Parameters = parameters};
}
where the array of MyType would look like this (JSON)
[
{key: "A", value: 1},
{key: "B", value: "Something else"}
]
so the resulting query should look like this:
SELECT * FROM root r WHERE ARRAY_CONTAINS([
{key: "A", value: 1},
{key: "B", value: "Something else"}
], r.Type)
and a document of the root collection would look like this
{
"Text": "I wanna be selected by you",
"Type": {"key": "A", "value": 1}
}
and should therefore be picked up by the above query.
Where as this document wouldnt be picked up
{
"Text": "Nah, you not gonna find me",
"Type": {"key": "C", "value": 1}
}
So basically how can I search for an array of JSON objects?

DocumentDB SQL where Array of Objects matches an array of strings

reference: DocumentDB SQL with ARRAY_CONTAINS
Question: Is there a better and more efficient query for what is happening below?
In the above reference question, the UDF was written to check if an object in the array had a match to the passed in string. In this variant, I am passing into the UDF an array of strings.
Now I have a working O(N^2) version that I would hope CosmosDB had a more efficient solution for.
function ScopesContainsNames(scopes, names){
var s, _i,_j, _ilen, _jLen;
for (_i = 0, _ilen = scopes.length; _i < _ilen; _i++) {
for (_j = 0, _jLen = names.length; _j < _jLen; _j++) {
s = scopes[_i];
n = names[_j];
if (s.name === n) {
return true;
}
}
}
return false;
}
My QUERY looks like this.
SELECT * FROM c WHERE udf.ScopesContainsNames(c.scopes, ["apples", "strawberries", "bananas"])
The following is an example of my Document:
{
"scopes": [
{
"name": "apples",
"displayName": "3048b61e-06d8-4dbf-a4ab-d4c2ba0a8943/a"
},
{
"name": "bananas",
"displayName": "3048b61e-06d8-4dbf-a4ab-d4c2ba0a8943/a"
}
],
"enabled": true,
"name": "dc1e4c12-95c1-4b7f-bf27-f60f0c29bf52/a",
"displayName": "218aea3d-4492-447e-93be-2d3646802ac6/a",
"description": "4aa62367-7421-4fb6-88c7-2699c9c309dd/a",
"userClaims": [
"98988d5b-38b5-400c-aecf-da57d2b66433/a"
],
"properties": {
"437d7bab-a4fb-4b1d-b0b9-f5111d01882a/a": "863defc1-c177-4ba5-b699-15f4fee78ea5/a"
},
"id": "677d4a49-a46c-4613-b3f6-f390ab0d013a",
"_rid": "q6I9AOf180hJAAAAAAAAAA==",
"_self": "dbs/q6I9AA==/colls/q6I9AOf180g=/docs/q6I9AOf180hJAAAAAAAAAA==/",
"_etag": "\"00000000-0000-0000-1ede-f2bc622201d5\"",
"_attachments": "attachments/",
"_ts": 1560097098
}
If i don't misunderstanding your requirement,you need to search the results where any name property of scopes array is included by the ["apples", "strawberries", "bananas"].
No need to use udf, please see the sample documents i made as below:
Using sql:
SELECT distinct c.scopes FROM c
join fruit in c.scopes
where Array_contains(["apples", "strawberries", "bananas"],fruit.name,false)
Result:

Observable contains array of ID to call another observable

I have a data structure in firebase
{
"name": "Sample",
"category": ["123456", "789012"]
}
The array of category contains ID which refers to documents in another collection. I can get the above document as Observable. What I really what as the end result is the below data structure
{
"name": "Sample"
"category": [
{
"name": "Category 1"
},
{
"name": "Category 2"
}
]
}
How can I bring this data? I don't think switchMap works for this. If so, can someone give an example of that?
You can try using flatMap and forkJoin. FlatMap allows you to chain multiple async requests together and forkJoin allows you to wait for all observables to return a value before continuing.
And you could wright something like this:
var finalData;
firstRequest('sample').flatMap((data) => {
// assuming data = { name: "Sample", catagory: [ "23123", "31321", ... ] }
finalData = data;
var observables = [];
data.catagory.forEach((c) => {
observable.push(secondRequest(c));
});
return forkJoin(observables);
}).flatMap((results) => {
// assuming results is an array like [ { name: "Catagory 1", ... } ]
finalData.category = results;
return finalData;
});

Ember Data FilterBy

I am trying to filter the data coming back from FindAll cause I only want data from a certain provider
// Data coming back from API
{
"-KDinaItb7lkHpai-DlG": {
"email": "johns#test.com",
"name": "John Smith",
"notes": "John is a great employee and is the best",
"phone": "215-543-9830",
"provider": "-KDhzbilOvv7Evuc5S_X"
},
"-KDjS0cCxFWQctcwXg0V": {
"email": "amanda#test.com",
"name": "Amanda Harrington",
"notes": "Amanda is a great employee",
"phone": "215-543-9830",
"provider": "-KDiokWebdhTNKTORWwn"
},
"-KDyf7pU_PyxRQSgFB59": {
"email": "lguy#test.com",
"name": "Larry Guy",
"notes": "He is a funny guy",
"phone": "702-454-2397",
"provider": "-KDhzbilOvv7Evuc5S_X"
}
}
// In the route
let providerId = model.get('provider').get('id');
​
this.store.findAll('employee').then(function(results) {
let prov = results.filterBy('provider', providerId);
​
console.log(prov);
});
When the console log happens and it returns an empty array. I think its because of the ID and its not looking at the nested object. Anyone got any thoughts?
Ok so your hash looks quite odd. Property name shouldn't be some generated hash.
code should be something like that.
I assume you have 1 wrapper object on index 0 within an array.
var filteredEmployees_promise = this.store.findAll('employee').then(function(results) {
var filteredResults = [];
Object.keys(Results[0]).forEach(key => {
var filteredObj = Results[0][key][providerId];
if(Ember.isPresent(filteredObj) {
filteredResults.pushObject(filteredObj)
}
});
return filteredResults;
});
And later
filterEmployees_promise.then(employees => { // Custom stuff })

All instances of a node by xxxx name

Is there a one liner or how can I get all instances of a named list in any node?
say I get jason where multiple nodes could have a sub collection called "comments". How can I get all nodes that contain a collection of "comments"?
Thanks,
If you can provide an example of the JSON, I can give you a definitive answer.
However, I can post some of the JSON I'm parsing and you can see how it works and possibly shape it to fit your needs.
"abridged_cast": [
{
"name": "Clark Gable",
"characters": ["Rhett Butler"]
},
{
"name": "Vivien Leigh",
"characters": ["Scarlett O'Hara"]
},
{
"name": "Leslie Howard",
"characters": ["Ashley Wilkes"]
},
{
"name": "Olivia de Havilland",
"characters": ["Melanie Hamilton"]
},
{
"name": "Hattie McDaniel",
"characters": ["Mammy"]
}
],
Notice how abridged_cast is an array of values, and one value in that array (characters) is an array itself.
Here's how I fetch the data:
var castMembers = (JArray) x["abridged_cast"];
foreach (var castMember in castMembers)
{
CastMember member = new CastMember();
member.Actor = (string) castMember["name"];
var characters = (JArray) castMember["characters"];
foreach (var character in characters)
{
member.Characters.Add((string)character);
movie.Cast.Add(member);
}
}

Resources