How to use 'where' in Firestore - android

In sql,we can use 'where' to select any data that we want.
How to do the same thing in firestore, I use if statement but it seems doesn't work

Suppose you want to select a specific user from users collection
angularFirestore.collection('users', ref => ref.where('username', '==', 'doe'))
You can join multiple where clause
angularFirestore.collection('users',
ref => ref.where('username', '==', 'doe')
.where('age', '>=', '20'))
But you can use range comparison only on one filed.
Right:
angularFirestore.collection('users',
ref => ref.where('age', '<=', '40')
.where('age', '>=', '20'))
Wrong:
angularFirestore.collection('users',
ref => ref.where('earning', '>=', '40000')
.where('age', '>=', '20'))

Related

Accessing JSON decoded into a HASH and an array of hash references

Given the following dumper output is there a way to iterate through each hash to list only the items under each results->id record? I want to be able to say things like:
print $results{1342}{'domain'};
and have the statement return testing11.com as a result.
Would I have to first read through all of results array and then use $results[$counter]{id} to access the data in there ? I'm not sure how to proceed.
$VAR1 = {
'end_time' => 1466017739,
'options' => {
'hour_offset' => '00',
'timezone' => 'America/New_York'
},
'field_headers' => {
'priority' => 'Priority',
'status' => 'Status',
'assignee_external_id' => 'Assignee external id',
'initially_assigned_at' => 'Initially assigned at'
},
'results' => [
{
'priority' => 'High',
'status' => 'Open',
'domain' => 'testing11.com',
'generated_timestamp' => 1546547669,
'id' => 1342
},
{
'priority' => 'Low',
'status' => 'Open',
'domain' => 'testing22.com',
'generated_timestamp' => 1464567669,
'id' => 7062
},
{
'priority' => 'Low',
'status' => 'Closed',
'domain' => 'testing33.com',
'generated_timestamp' => 1464267669,
'id' => 432
}]
}
Your dump shows a hashref containing a scalar, two hashrefs, and an arrayref. The arrayref has hashrefs for elements. If you want to retrieve specific elements from it, you need to know the index.
$top_level->{results}->[0]->{domain}; # is 'testing11.com'
$top_level->{results}->[0]->{status}; # is 'open'
To iterate through it dereference the array
foreach my $result (#{ $top_level->{results} }) {
print "$result->{id}\n";
}
Or you can just get values from all results elements for a particular key, say for id
my #ids = map { $_->{id} } #{ $top_level->{results} };
say "#ids";
Prints
1342 7062 432
Note that with nested structures, which contain references, you can also use syntax
$top_level->{results}[0]{domain}; # is 'testing11.com'
The -> is optional between subscripts, see rule 3. in Using References in perlref.
When the hash keys are strings they should be quoted
$top_level->{'results'}[0]{'domain'};
However, a syntax shortcut allows us to omit quotes on barewords. But if there is anything other than a bareword inside {} it will be interpreted as an expression and evaluated. So if in any doubt use quotes. You want consistent notation throughout.
Resources: Tutorial perlreftut, reference perlref and data structures cookbook, perldsc.
A direct solution is given in stevieb's answer, creating a reverse lookup. Copied here for reference
my $results = $VAR1->{results};
my %by_ip = map {$_->{id} => $_} #$results;
print "$by_ip{1342}->{domain}\n";
You need to transform the inner $results array into a new hash:
my $results = $VAR1->{results};
my %modded = map {$_->{id} => $_} #$results;
print "$modded{1342}->{domain}\n";
Output:
testing11.com
What that does is for each hash reference inside #$results, takes the value of the id key, sets it as a new key inside of a new hash (%modded), and then assigns the whole hash ref we're working with to the value of that numbered key.
For completeness, TIMTOWTDI-ness and -Ofun if you use the latest perl (use v5.24;), with postfix dereferencing (enabled by default), and experimental support for reference aliasing (use feature 'refalias';) then you can dereference $VAR1 and assign it to an alias (%data) which you can then access as a regular hash:
use v5.24 ;
use feature 'refaliasing';
my $VAR1 = [AS ABOVE] ;
foreach \my %data ( $VAR1->{results}->#* ) { say $data{domain} };
I like this usage (though at this point it is far from an accepted "idiom") because you invoke the dereferencing syntax "once" - either the postfix or traditional form - and then get a data structure where it is not necessary to use -> inside the block .
Of course you can do this by copying into a temporary hash. but aliasing can be seen as "more efficient and readable" (cf. Data::Alias).
Further References:
The Perl Data Structures Cookbook documentation that comes with perl (perldoc perldsc in your shell)
An accessible PerlTricks article on references.
brian d foy's introduction to use feature 'refalias' and the perldelta entry for the feature for version 5.22

Why does my Perl code overwrite the location of my value in the spreadsheet?

I'm trying to create a chart within a spreadsheet (using Spreadsheet::Write).
I only want to put 1 category and 1 value but somehow the value of, well, my 'value' gets overwritten.
I'm adding the series like this:
my $chart = $workbook->add_chart( type => 'column', embedded => 1 );
$chart->add_series(
categories => '='.$worksheet->get_name().'!$A$'.$aecCells[0],
values => '='.$worksheet->get_name().'!$B$'.$aecCells[0],
name => $aecParams[0],
);
print "\n--->".$aecCells[0];
$chart->set_title (name => 'Plots');
$worksheet->insert_chart('I2', $chart );
Technically, it should take the value from the Bx cell but it's not :/, it's taking the one from Ax ...which is not really a numeric value but a string so I get a useless graph.
Any ideas as to what I'm doing wrong?
Putting the name of the worksheet inside quotes and using cell ranges should solve your issue:
$chart->add_series(
categories => '=\''.$worksheet->get_name().'\'!$A$1:$A$'.$aecCells[0],
values => '=\''.$worksheet->get_name().'\'!$B$1:$B$'.$aecCells[0],
name => $aecParams[0],
);

How to pass a a string variable as “query” for get Manager call?

I'm trying to make this simple call:
DataB::testTable::Manager->get_testTable( query => [ id => $id, name => $name ] )
which works perfectly fine. But is it possible to pass a variable for the query. Something like:
$query = "id => $id , name => $name";
DataB::testTable::Manager->get_testTable( query => [ $query ] );
or something similar.
Strings and complex data structures are completely different things.
Strings are a sequence of codepoints/graphemes/bytes (depends how you're looking). Strings are dumb. Strings are not good at containing complex and/or hierarchical data. (Point in case: XML is pure pain)
However, you can put any Perl data structure into a scalar variable, using references. Square brackets create a reference to an anonymous array.
These groups of lines are equivalent except for the fact that a variable name is introduced:
DataB::testTable::Manager->get_testTable( query => [ id => $id, name => $name ] );
my #query = (id => $id, name => $name);
DataB::testTable::Manager->get_testTable(query => \#query); # the "\" takes a reference to a value
my #query = (id => $id, name => $name);
DataB::testTable::Manager->get_testTable(query => [#query]); # using "[]" to make the arrayref. The reference points to a copy of #query.
# this solution is probably best:
my $query = [ id => $id, name => $name ]; # "[]" makes an arrayref
DataB::testTable::Manager->get_testTable(query => $query);
Using references to data structures is better than using strings.
(You could interpret a string as Perl source code via eval. This is extremely powerful, but not everything stringifies to a form that can be eval'd into an equivalent data structure. Don't use string-eval, except for well thought out metaprogramming.)
For further info on references and complex data structures, perlref, perlreftut and perldsc might be interesting.

MongoDB Distinct Values

I m using this code to find specific text into database then i will load into page with mojolicious.Is this method is good or how fast it is?
use MongoDB;
use Data::Dump q(dump);
my $connection = MongoDB::Connection->new(host => 'localhost', port => 27017);
my $database = $connection->test;
my $col = $database->user;
my $r3 = $database->run_command([
"distinct" => "person",
"key" => "text",
"query" =>""
]);
for my $d ( #{ $r3->{values} } ) {
if ($d=~ /value/){
print "D: $d\n";
}
}
distinct command can certainly work (and it seems that it does), so it's good. It is also probably the fastest way to do this (the implementation just opens appropriate index, reads from it and populates hash table, IIRC).
Note, however, that it will fail with error if total size of distinct values is greater than BSON size limit (16MB currently).
If you ever run into this, you'll have to resort to slower alternatives. MapReduce, for example.

How to convert a Perl hash-of-hashes to a more flexible data structure?

In a quick-and-dirty Perl script, I have a data structure like this:
$tax_revenue{YEAR}{STATE}{GOVLEV}{TAX} = integer
The hash keys assume values like this:
YEAR: 1900 .. 2000
STATE: AK, AL, ... WY
GOVLEV: state, local
TAX: type of tax (income, sales, etc.)
In addition, the hash keys are unique. For example, no value for the TAX parameter collides with a value for another other parameter.
I am starting a medium-sized project working with this data and I would like to implement the data structure in a more flexible way. I don't know all of the data-retrieval functionality I will need yet, but here are some examples:
# Specify the parameters in any order.
Tax_rev( qw(1902 WY state property) );
Tax_rev( qw(state property 1902 WY) );
# Use named parameters.
Tax_rev(year => 1902, state => 'WY', govlev => 'state', tax => 'property');
# Use wildcards to obtain a list of values.
# For example, state property tax revenue in 1902 for all states.
Tax_rev( qw(1902 * state property) );
My initial inclination was to keep storing the data as a hash-of-hashes and to build one or more utility functions (probably as part of a class) to retrieve the values. But then I wondered whether there is a better strategy -- some way of storing the underlying data other than a hash-of-hashes. Any advice about how to approach this problem would be appreciated.
If you want a pure Perl implementation, you could build an array of hashes:
my #taxdata = (
{ year => 1902, state => 'WY', level => 'state', type => 'property', amount => 500 },
# ...
);
my #matches = grep {
$_->{year} == 1902 &&
$_->{level} eq 'state' &&
$_->{type} eq 'property'
} #taxdata;
That's flexible if you want to run arbitrary queries against it, but slow if you want to be able to get to a specific record.
A better solution might be a database with a single table where each row contains the fields you listed. Then you could write an SQL query to extract data according to arbitrary criteria. You can use the DBI module to handle the connection.
Please consider putting the data in an SQLite database. Then, you have the flexibility of running whatever query you want (via DBI or just the command line interface to SQL) and getting data structures that are suitable for generating reports for taxes by state or states by taxes or taxes for a given year for all states whose names begin with the letter 'W' etc etc. I presume the data are already in some kind of character separated format (tab, comma, pipe etc) and therefore can be easily bulk imported into an SQLite DB, saving some work and code on that end.
I would advise you to look into an object system such as Moose. The learning curve isn't too steep (or steep at all) and the benefits will be enormous. You'd start with something like:
package MyApp;
use Moose; # use strict automagically in effect
has 'year' => ( is => 'ro', isa => 'Int', required => 1 );
has 'state' => ( is => 'ro', isa => 'Str', required => 1 );
has 'govlev' => ( is => 'ro', isa => 'Str', required => 1 );
has 'tax' => ( is => 'ro', isa => 'Str', required => 1 );
Then in your main program:
use MyApp;
my $obj = MyApp->new(
year => 2000,
state => 'AK',
govlev => 'local',
tax => 'revenue'
);
# ...
With the flexibility of MooseX::Types you can go on to declare your own type classes, with enums, etc.
Once you go Moose, you never look back :)
Check out Data::Diver: "Simple, ad-hoc access to elements of deeply nested structures". It seems to do exactly what you want from Tax_rev:
use Data::Diver qw( Dive );
...
$tax_revenue{ 1900 }{ NC }{ STATE }{ SALES } = 1000;
...
Dive( \%Hash, qw( 1900 NC STATE SALES ) ) => 1000;
Dive( \%Hash, qw( 1901 NC STATE SALES ) ) => undef;
If you aren't going to use objects, I think that data structure will work just fine.
Here is an example of Tax_rev(). It isn't full featured, but you can give it the 4 arguments in any order. If you actually use it you might want to check the inputs.
my $result = Tax_rev( \%data, qw(state property 1902 WY) );
use strict;
use warnings;
use 5.010;

Resources