Selecting data in Firebase - firebase

Saw the Firebase / Angular video you did and immediately got very excited about the project I have just started. One thing I am struggling to get my head around is how to select data at sub-levels. What I mean is: say I had something like this:
How can I select all records with the agent 'agent_1' and/or records with the box_id greater than 600 (plus other fields) without creating lots of indexes for each search term? I don't really want to download all the data to the client and then loop through the records as there will eventually be a lot of data.
Eventually, the app should be able to filter data on different fields simultaneously. For example, I would have a select box for agents, which may return all the agent_1 records. Then I would add the filter 'all boxes with id > 600' and then perhaps 'box weight > 24kg' etc.
It seems from what I have read, this is only possible by having an id field for each record, and then an index dataset for each field one would like to search against. This is simple enough for one field. However, I guess the only way to filter the data with further fields would be to get the ids on the next index dataset and do the filtering on the client.
Am I right in this approach? It seems quite long-winded.
What would be awesome would be to be able to do this:
https://xxxxx.firebaseio.com/boxes/?agent=agent_1/?box_id>600
Just a thought! :-)
Thanks!

first Import angular like following
import { AngularFireDatabase } from "angularfire2/database";
also import in app.module.ts
secondly inject database into your constructor an like
constructor(private database:AngularFireDatabase ){
const rootRef = database.database.ref();
var data= rootRef.child("boxes").orderByChild("agent").equalTo("agent_3")
}

Related

Store a manipulated collection in Power Apps

(1) In my Canvas App I create a collection like this:
Collect(colShoppingBasket; {Category: varCategoryTitle ; Supplier: lblSupplier.Text ; ProductNumber: lblProductNumber.Text });;
It works - I get a collection. And whenever I push my "Add to shopping basket" button, an item are added to my collection.
(2) Now I want to sort the collection and then use the sorted output for other things.
This function sorts it by supplier. No problems here:
Sort(colShoppingBasket; Supplier)
(3) Then I want to display the SORTED version of the collection in various scenarios. And this is where the issue is. Because all I can do is manipulate a DISPLAY of the collection "colShoppingBasket" - (unsorted).
(4) What would be really nice would be the option to create and store a manipulated copy of the original collection. And the display that whereever I needed. Sort of:
Collect(colShoppingBasketSORTED; { Sort(colShoppingBasket; supplier) });; <--- p.s. I know this is not a working function
You could use the following:
ClearCollect(colShoppingBasketSorted, Sort(colShoppingBasket, Supplier))
Note that it is without the { }
This will Clear and Collect the whole colShoppingBasket sorted.
If you want to store the table in a single row in a collection, you can use
ClearCollect(colShoppingBasketSortedAlternative, {SingleRow: Sort(colShoppingBasket, Supplier)})
I wouldn't recommend this though because if you want to use the Sorted values you'd have to do something like this:
First(colShoppingBasketSortedAlternative).SingleRow -> this returns the first records of the colShoppingBasketSortedAlternative then gets the content of the SingleRow column, which in this case is a Collection
Note: You will need to replace the , with ; to work on your case

Dropdown from values of a database field

I have an issue related to the data filtering. I have a Google Drive table to store data, and I want to show one field of this data source in a dropdown to make a filter by this field (Country).
The problem is that this dropdown filter it's only showing the countries that appears on the current page of the list. For example, if in the first page appears one country (Thailand) on the dropdown I'll only see Thailand.
If we move to the second page of the list we have another two countries (Spain and Portugal) and then the dropdown will only show Spain and Portugal.
What I really want is a dropdown which shows all the countries, no matter if they aren't on the current page, but I don't know how to fix it. ​
​This the the configuration of the Country Selector:
In the help, it's said we should use #datasource.model.fields.COUNTRY.possibleValues,
but if I use this paramater as Options, nothing is displayed in the selector.
I have spend a lot of hours trying to fix this issue and I don't find the solution, and I would like to check with you if it's an issue or I'm doing something wrong...
Could you help me?
You are using the same datasource for your dropdown and table and by #distinct()#sort() you are filtering items that are already loaded to browser (opposed to the whole dataset stored in database).
You need to have a separate datasource for your dropdown. There are at least three techniques to do this:
Possible values
You can predefine allowed values for your Country field and use them to populate drop down options both in create form and table filtering #datasource.model.fields.Country.possibleValues as you mentioned in question:
Create model for countries
By introducing dedicated related model for countries you can get the following benefits:
normalized data (you will not store the same country multiple times)
you'll be able to keep your countries list clean (with current approach there is possibility to have the same country with different spellings like 'US', 'USA', 'United State', etc)
app users when they create new records will be able to choose the country they need from dropdown (opposed to error prone typing it every time for all new records).
your dropdown bindings will be as simple as these:
// for names
#datasources.Countries.items..Names
// for options
#datasources.Countries.items.._key
// for value
#datasource.query.filters.Country._key._equals
Create Calculated Model
With Calculated Model you'll be able to squeeze unique country values from your table. You server query script can look similar to this:
function getUniqueCountries_() {
var consumptions = app.models.Consumption.newQuery().run();
var countries = [];
consumptions.reduce(function (allCountries, consumption) {
if (!allCountries[consumption.Country]) {
var country = app.models.CountryCalc.newRecord();
country.Name = consumption.Country;
countries.push(country);
allCountries[consumption.Country] = true;
}
}, {});
return countries;
}
However with growth of your Consumption table it can give you significant performance overhead. In this case I would rather look into direction of Cloud SQL and Calculated SQL model.
Note:
I gave a pretty broad answer that also covers similar situations when number of field options can be unlimited (opposed to limited countries number).

How to use cursors for navigating to previous pages using GQL and the new gcloud-java API?

I'm using the new gcloud-java API (https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-datastore/src/main/java/com/google/cloud/datastore) for working with the Cloud Datastore. My specific question is on using GQL for pagination with cursors. I was able to page through the results one page at a time in the forward direction using cursors, but not having any luck with paging backwards.
Example Scenario:
Let's say I've 20 entities in a Kind with IDs 1 through 20. I have a page size of 5. Once I'm on the 3rd page (IDs 11 through 15), if I need to go one page back; i.e. retrieve IDs 6 through 10, what would be the correct GQL/sample code? Again, I prefer not to use offset with a number, but would like to use Cursors.
From what I can tell (actually tested), it looks like one needs to keep track of Start/End cursors for each page as they navigate in the forward direction, then use the saved cursors when there is a need to go back. I just want to make sure if this is the correct/only way or there is a simpler way to accomplish this.
Thanks in advance for your help.
If you add to your original query a sort by key (appended to the end of your "order by" clause), you should be able to reverse each property's sort order and use the latest cursor from your original query to get results in reverse.
Suppose you've iterated through some of the values from your forward query's QueryResults. You can call QueryResults's cursorAfter() method, which will return a cursor pointing right after the last result you saw from your original query. Now you can issue a new query (with the opposite sort order on each property, including the key property) using that cursor as the start cursor. You'll probably want to skip the first result, since it will be the last result you saw from the original query.

Hiding a specific object of a catalog results

There is a way to hide a specific object of my catalog results?
I have a configuration file that I don't want to show.
I'm filtering by id, but it seems so ugly.
from Products.CMFCore.utils import getToolByName
def search(context):
catalog = getToolByName(context, 'portal_catalog')
items = catalog()
for item in items:
if item.id != "config_file":
'do something'
If you are already hiding the object from the navigation tree, you can filter on the same property by testing for exclude_from_nav:
items = catalog()
for item in items:
if item.exclude_from_nav:
continue
# do something with all objects *not* excluded from navigation.
It is harder to filter out things that don't match a criteria. Using a test on the brain object like the above is a perfectly fine way to remove a small subset from your result set.
If you need handle a larger percentage of 'exceptions' you'll need to rethink your architecture, perhaps.
With Products.AdvancedQuery you can create advanced queries and filtering on catalog results. See also this how to.
In the general case, setting a content item's expiration date to some past date hides it from search results (so long as the user does not have the Access inactive portal content permission).
It's an easy way to hide pieces of content that should be visible to all, but that you don't want cluttering up search results e.g. a Document that serves as the homepage.
I always use 1st Jan 2001 as the date so I can easily recognise when I've used this little 'hack'.

How do you get a Min() or Max() in drupal using views?

I'm using Drupal's Views 2, and need to retrieve min values from fields in a custom table. The query for this is easy if I were writing it by hand--something like, "SELECT foo, min(bar) FROM table GROUP BY foo." But how would I do this using Views? I've already defined the table in a views.info file, so there's no trouble getting views to see the table. It's the Min() part of the query I just don't understand. My next stop will be the Views API documentation, but if someone can just provide the outline for how to do this quickly, I would greatly appreciate it.
New answer to an old question, but something like this will work. You need to create a custom field handler and then wrap the field as follows:
class views_handler_custom_field extends views_handler_field {
function query() {
$this->ensure_my_table();
$this->field_alias = $this->query->add_field("MAX({$this->table_alias}", "{$this->real_field})",$this->table_alias . "_" . $this->real_field);
}
}
Use aggregation from advanced configuration of views. After this is set
yes you can select max, min or any other selector to fields.
Test your results but it should work well
Alternatively in some cases you can sort your data ascending or
descending and then just pick one to be shown on the view. Can be
problematic when displaying multiple fields or so.
After testing first one seems to be faster at least on small scale.
One could consider the modules groupby and views_calc, but I assume they are not acceptable for you.
Additionally, you can accomplish this with a custom module.

Resources