Home > Blockchain >  Firestore - Can you query fields in nested documents?
Firestore - Can you query fields in nested documents?

Time:09-29

I currently have a data structure like this in Firebase Cloud Firestore

Database
  ProductInventories    (collection)
    productId1        (document)
      variantName     (collection)
        [auto-ID]     (document)
          location: "Paris"
          count: 1334

How would I make a structuredQuery in POST to get the count for location `Paris'?

Intuitively it might have been a POST to https://firestore.googleapis.com/v1/projects/projectName/databases/(default)/documents/ProductInventories/productId1:runQuery with the following JSON

{
    "structuredQuery": {
        "from": [
            {
                "collectionId": "variantName",
                "allDescendants": true
            }
        ],
        "where": {
            "fieldFilter": {
                "field": {
                    "fieldPath": "location"
                },
                "op": "EQUAL",
                "value": {
                    "stringValue": "Paris"
                }
            }
        }
    }
}

With this I get error collection group queries are only allowed at the root parent, which means I need to make the POST to https://firestore.googleapis.com/v1/projects/projectName/databases/(default)/documents:runQuery instead. This however means I'll need to create a collection group index exemption for each variant (variantName) I have for each productId.

Seems like I would be better off to have below variantName collection level, the location as the name of the document, and I can then access the count directly without making a query. But seems to me the point of NoSQL was that I could be less careful about how I structure the data, so I'm wondering if there's a way for me to make the query as is with the current data structure.

CodePudding user response:

have you tried something like this?

fb.firestore().collection('ProductInventories')
.doc('productId1')
.collection('variantName')
.where('location', '==', 'Paris')
.get()
.then(res=>{

   res.data().docs.forEach((product, i)=>{
      console.log('item '   i   ': '   product.count);
   })

});

CodePudding user response:

Using collection names that are not known ahead of time is usually an anti-pattern in Firestore. And what you get is one of the reasons for thst: you need to be able to create a collection group query across documents in multiple collection, you need to be able to define an index on the collection name - and that requires that you know those some time during development.

As usual when using NoSQL databases, you can modify/augment your data structure to allow the use-case. For example, if you create a single subcollection for all variants, you can give that collection a fixed name, and search for paris and $variantName in there. This collection can either be a replacement of your current $variantName collections, or an addition to it.

  • Related