0

I'm using Firestore to store data for multiple entities. In this example, each document is a company with details on the products it sells, and each product is associated with multiple keywords. Example structure:

Document 1:

    company_name: 'Company 1',
    products: [
        {
            name: 'Green tea',
            keywords: ['green tea', 'healthy, 'matcha']
        },
        {
            name: 'Sushi',
            keywords: ['sushi', 'rice', 'healthy']
        }
    ]

Document 2:

    company_name: 'Company 2',
    products: [
        {
            name: 'Apple',
            keywords: ['fruit', 'healthy']
        },
        {
            name: 'Cake',
            keywords: ['dessert', 'sweet']
        }
    ]

I would like to search for companies that sell products with certain keywords. For example, by searching for the keyword healthy, both documents Company 1 and Company 2 would be returned, as they both sell foods with that keyword. How would I do this with Firestore filtering/searching?

user2181948
  • 1,646
  • 3
  • 33
  • 60

1 Answers1

2

The way you have your data structured now, with multiple field array elements containing values to search, it's not possible to have a single query find everything you want. The problem here is the arrays. It's simply not possible to search the nested contents of array fields.

When you have array elements that need to be matched individually with queries, they should instead be individual documents in a collection. Yes, that's more reads and writes, but that also means your queries become possible.

Imagine instead if your two documents didn't contain a products array field, and instead each document contained a subcollection called products where each item had a field called keywords.

companies (collection)
  document 1 (doc)
    company_name: string field
    products (subcollection)
      keywords: string array field

With this, you could then do a collection group query across all products across all companies like this (in JavaScript):

db.collectionGroup("products").where("keywords", "array-contains", keyword)

where keyword is the word you're looking for.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441