Select a matching element from a dataset with multiple conditions and inputs - programming [duplicate] - firebase

This question already has answers here:
Query based on multiple where clauses in Firebase
(8 answers)
Closed last year.
I'm using FirebaseRecyclerAdapter and pass FirebaseRecyclerOptions with some query into constructor. Each item has number of fields including timestamp a and another integer field b. So I want items with older a but less b to be on top of list. It's easy to implement with sqlite, but not so easy with nosql. It seems I need to add some extra field which keeps both fields:
String.valueOf(a) + String.valueOf(b) but how to achieve asc / desc properties?
Loading the whole list and sorting in Java is not an option.

Unfortunately, Firebase Realtime database does not support queries on multiple properties, supports only queries on a single child property. So, you're correct in guessing that you'll need to create an extra field to keep both fields. So to achieve this, you need to create a new field which in your database should look like this:
Firebase-root
|
--- itemId
|
--- a: valueOfA
|
--- b: valueOfB
|
--- a_b: valueOfA_valueOfB
So as you see, the a_b property combines the values that you want to filter on.
Unlike Firebase Realtime database, Cloud Firestore allows compound queries. You should take a look at this. So a query as the one below is allowed in Cloud Firestore without creating a combined property.
itemIdRef.whereEqualTo("a", "valueOfA").whereEqualTo("b", "valueOfB");
When you order strings this is the normal ordering method. A quick fix would be to add two zeros before each second element like this: "1516428687_001", "1516428687_002", "1516428687_012". Now your order will be fine. For more explanations, please see my answer from this post.

Related

When I use DataSnapshot with if else then it shows null value instead of original value, why? [duplicate]

This question already has answers here:
Query based on multiple where clauses in Firebase
(8 answers)
Closed last year.
I'm using FirebaseRecyclerAdapter and pass FirebaseRecyclerOptions with some query into constructor. Each item has number of fields including timestamp a and another integer field b. So I want items with older a but less b to be on top of list. It's easy to implement with sqlite, but not so easy with nosql. It seems I need to add some extra field which keeps both fields:
String.valueOf(a) + String.valueOf(b) but how to achieve asc / desc properties?
Loading the whole list and sorting in Java is not an option.
Unfortunately, Firebase Realtime database does not support queries on multiple properties, supports only queries on a single child property. So, you're correct in guessing that you'll need to create an extra field to keep both fields. So to achieve this, you need to create a new field which in your database should look like this:
Firebase-root
|
--- itemId
|
--- a: valueOfA
|
--- b: valueOfB
|
--- a_b: valueOfA_valueOfB
So as you see, the a_b property combines the values that you want to filter on.
Unlike Firebase Realtime database, Cloud Firestore allows compound queries. You should take a look at this. So a query as the one below is allowed in Cloud Firestore without creating a combined property.
itemIdRef.whereEqualTo("a", "valueOfA").whereEqualTo("b", "valueOfB");
When you order strings this is the normal ordering method. A quick fix would be to add two zeros before each second element like this: "1516428687_001", "1516428687_002", "1516428687_012". Now your order will be fine. For more explanations, please see my answer from this post.

Retrive all collection except one document id Firebase [duplicate]

This question already has answers here:
Firestore: how to perform a query with inequality / not equals
(7 answers)
Closed 2 years ago.
I want to retrieve all the collections except one document id. I have following query it will get all data by validating collection field. however i want to get all data except one document.
await Firestore.instance.collection('tbl').where('id',isEqualTo:textId).getDocuments().then(
(data){
dataRowCount= data.documents.length;
}
);
Firestore doesn't offer any way to exclude documents from a query. You must can only filter for known values that you're looking for, or ranges of values. If you want to skip a document, you will have to check the query results in your code and omit the one you don't want

Is it possible to query collectionGroup on a specific collection? [duplicate]

This question already has answers here:
collectionGroup within a certain path
(2 answers)
Closed 3 years ago.
I have a user collection, and within that collection there's a collection name groups, which then has groupItems. Is it possible to run a query for all groupItems for a specific user?
I could run a global version like:
db.collectionGroup('groupItems')
but that is overkill for me, I'm looking for something like:
db.collection('users').doc(uid).collection('groups').collectionGroup('groupIems').where('categoryOnly', '==', true)
Is this possible?
The architecture of the collections looks like this:
Users
---> User
------> Collections
---------> GroupA
------------> GroupAItems
---------------> GroupAItem1
---------------> GroupAItem2
---------> GroupB
------------> GroupBItems
---------------> GroupBItem1
---------------> GroupBItem2
Ideally I could call for all Group Items instead of first calling for groups and getting [GroupA, GroupB...], and then calling for GroupA's items, then GroupB's, etc.
Update: it turns out that querying a specific path may be possible after all, thanks to how FieldPath.documentId() is indexed for collection group indexes. Check #samthecodingman's answer here: https://stackoverflow.com/a/68049847
Happy answer above 👆
Old answer below 👇
There is currently no way to limit a collection group to just collections under a specific path. All collection group queries get documents from all collections with the specified name.
So the only way to currently query a subset of your groups is to use a naming scheme that allows you to uniquely address them.
Also see:
Does collection group queries get data from all collections with the same name?
collectionGroup within a certain path

Firebase queries and compound indexes

I have the following document structure in firebase:
{
typeId: number,
tripId: number,
locationId: string,
expenseId: number,
createtAt: timestamp
}
I want to query this collection using different 'where' statement everytime. Sometimes user wants to filter by type id and sometimes by locationId or maybe include all of the filters.
But it seems like I would need to create a compound index of each possible permutation? For example: typeId + expenseId, typeId + locationId, location + expenseId, etc, otherwise it doesn't work.
What if I have 20 fields and I want to make it possible to search across all of these?
Could you please help me to construct a query and indexes for the following requirement: Possibility to query across all fields, query can contain one, two, three, all or no fields included in where clause and always has to be ordered descending order by createdAt.
Cloud Firestore automatically creates indexes for the individual fields of your documents. So it can already filter on each field without you have to manually add these indexes.
In many cases it is able to combine these indexes to allow queries on field combinations, by performing a so-called zig-zag-merge-join.
Custom additional indexes are typically only needed once you add an ordering-clause to your query, in addition to filter clauses. If you have such a case, the Firestore client will log an error telling you exactly what index to create (with a link to the Firestore console that is prepopulated to created the index for you).

Using timestamp as an Attribute in DynamoDB

I'm quite new to DynamoDB, but have some experience in Cassandra. I'm trying to adapt a pattern I followed in Cassandra, where each column represented a timestamped event, and wondering if it will carry over gracefully into DynamoDB or if I need to change my approach.
My goal is to query a set of documents within a date range by using the milliseconds-since-epoch timestamp as an Attribute name. I'm successfully storing the following as each report is generated with each new report being added under its own column:
{ PartitionKey:customerId,
SortKey:reportName_yyyymm,
'#millis_1#':{'report':doc_1},
'#millis_2#':{'report':doc_2},
. . .
'#millis_n#':{'report':doc_n}
}
My question is, given a millisecond-based date range, and the accompanying Partition and Sort keys, is it possible to query the set of Attributes that fall within that range or must I retrieve all columns for the matching keys and filter them at the client?
Welcome to the most powerful NoSQL database ;)
To kick off with the positive news, there is no way to query out specific attributes. You can project certain attributes in a query. But you would have to write your own logic to determine which attributes or columns should be included in the projected query. To get close to your solution you could use a map attribute inside an item with the milliseconds as a key. But there is another thing you have to be aware of when starting on this path.
There is a maximum total item size of 400KB for each item in DynamoDB, including key and attribute names.(Limits in DynamoDB Items) This means you can only store so many attributes in an item. This is especially true if you intend to put the actual report inside of the attribute. Which I would advise against, also because you will be burning up read capacity units every time you get one attribute out of the whole item. You would be better of putting this data in a separate table with the keys in the map. But truthfully in DynamoDB I would split this whole thing up, just add the milliseconds to the sort key and make every document its own item. That way you can directly query to these items and you can use the "between" where clause to select specific date-time ranges. Please let me you meant something else.

Resources