Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore: How to query data from a map of an array

Here is the schema for test db: enter image description here

I want to write a query that can get all the documents where contacts have id=1 in any of the array index.

I have checked array_contains operator for firestore but the thing is my array have map which then have field id.

Thanks

like image 283
john Avatar asked Feb 08 '19 22:02

john


People also ask

How do I query multiple values in firestore?

With the in query, you can query a specific field for multiple values (up to 10) in a single query. You do this by passing a list containing all the values you want to search for, and Cloud Firestore will match any document whose field equals one of those values.

How do I get data from Cloud Firestore?

Get data with Cloud Firestore. There are two ways to retrieve data stored in Cloud Firestore. Either of these methods can be used with documents, collections of documents, or the results of queries: Call a method to get the data. Set a listener to receive data-change events.

Is it possible to chaining multiple values in a FireStore query?

Currently, this is only supported with one value, so don’t try chaining more than one of these in a single query. const col = firestore.collection('carts'); const query = col.where('items', 'array-contains', 'fruit loops') query.get(...)

What is array-contains in Firebase?

Firebase introduced an array-contains operator that can be used with where to query array fields. It will return all documents that contain a the provided value in the array. Currently, this is only supported with one value, so don’t try chaining more than one of these in a single query.


4 Answers

You currently can't build a query that looks for an object field within an array. The only things you can find in an array are the entire contents of an array element, not a part of an element.

With NoSQL type databases, the usual practice is to structure you data in a way that suits your queries. So, in your case, you're going to have to structure you data to let you find documents where an array item contains a certain string. So, you could create another array that contains just the strings you want to query for. You will have make sure to keep these arrays up to date.

You could also reconsider the use of an array here. Arrays are good for positional data, but unless these contacts need to be stored in a certain order, you might want to instead store an object whose keys are the id, and whose field data also contains the id and name.

like image 182
Doug Stevenson Avatar answered Oct 19 '22 01:10

Doug Stevenson


As Doug said, you can't query it, but, if you could structure your data to something that looks like this

  1. Store your data as a map
  2. Use id as key and name as value
  3. Now you can write a query that can get all the documents where contacts have id=1
db.collection("test").where("contacts.1", ">=", "").get()
like image 27
MOhan Avatar answered Oct 19 '22 00:10

MOhan


If you have an array of maps or objects and want to get the docoments that contains this specific map/object like this ? array_of_maps.png

you can use

queryForCategory(categName: string, categAlias: string): Observable[] {
    firestore.collection('<Collection name>', ref =>

        ref.where('categories',
          "array-contains", {
            "alias": categAlias,
            "title": categName
          }
like image 1
Hassan Gad Avatar answered Oct 19 '22 02:10

Hassan Gad


One soulions is as @Doug said, to add array with the data you need to query, and keep it uptodate.

Another solution is to make contacts as sub collection of the document, an then you could make queries of the contacts and get its parrent.

enter image description here

final Query contacts = db.collectionGroup("contacts").whereEqualTo("id", 1);
for (DocumentSnapshot document : querySnapshot.get().getDocuments()) {
  System.out.println(document.getId());
  System.out.println(document.getString("parent_id"));
}

If you don't want to add parent as another field, you can get it from parent reference, check this answer https://stackoverflow.com/a/56223319/1278463

snapshot.getRef().getParent().getParent().collection("people")

https://firebase.google.com/docs/firestore/query-data/queries#collection-group-query

like image 1
Borislav Gizdov Avatar answered Oct 19 '22 02:10

Borislav Gizdov