2

I'm trying to query my firestore database to find all documents in a collection that include a certain object in an array field. So say my database has an articles collection like so:

articles:
  [
    {
      id: "1",
      title: "First Article",
      comments:[]
      relatedArticles:[
        {
          id: "2",
          title:"Second Article"
        },
        {
          id: "3",
          title:"Third Article"
        },
      ]
    },
    {
      id: "2",
      title: "Second Article",
      comments:[]
      relatedArticles:[
        {
          id: "1",
          title:"First Article"
        }
      ]
    }
    {
      id: "3",
      title: "Third Article",
      comments:[]
      relatedArticles:[
        {
          id: "1",
          title:"First Article"
        }
      ]
    }
  ]

Every article in the articles collection has an array field (relatedArticles) which includes a set of objects each including both the id AND title of the related article. Say I wanted to query the database for all articles that have article 1 in their related articles field. How would I go about that assuming that this structure cannot be modified. I have tried the following to no avail:

firestore().collection("articles")
  .where("relatedArticles", "array-contains", {title: "First Article", id: "1"})

Is this feasible? And if not, what is?

  • 1
    Did you try the query you propose?? Because, if I am not mistaking, this is exactly the way you should do it! See https://stackoverflow.com/questions/54081799/firestore-to-query-by-an-arrays-field-value/54082731#54082731 – Renaud Tarnec Feb 25 '19 at 15:10
  • I have and it won't return anything. – Ahmed Refaat Feb 25 '19 at 15:12
  • Are you sure `articles` is a Firestore collection and not an array? – Renaud Tarnec Feb 25 '19 at 15:13
  • @RenaudTarnec Yes, articles is definitely a db collection. Are there any caveats associated with the proposed approach? Does, say, the ordering of the properties matter (id before title vs title before id) in either query or db record? – Ahmed Refaat Feb 25 '19 at 15:19
  • "Does the ordering of the properties matter" -> I don't know, I've never tried. Does it work if you reverse the object elements/properties? – Renaud Tarnec Feb 25 '19 at 15:22

1 Answers1

1

When doing array-contains searches, you can only match entire elements of an object in the array. You can't pick out a deeper field of an object in an array, as you are trying to do now.

If you want to satisfy this query, you will need some other field in your document that is searchable. Perhaps an array of only related document IDs will work for you. It is common to duplicate data in NoSQL database like this in order to satisfy queries.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • So, as some other commenter had suggested, matching the entire object in the array won't work? Like this: `firestore().collection("articles") .where("relatedArticles", "array-contains", {title: "First Article", id: "1"})` – Ahmed Refaat Feb 25 '19 at 17:19
  • You can match the entire object. You must provide an object that's structurally identical to the one in the array. But it looks like your array items are rather large, which is a lot of information to know ahead of time. You can't single out an embedded array inside a top-level field array (such as `relatedArticles`). You can only search on the top-level field array. – Doug Stevenson Feb 25 '19 at 17:22
  • By structurally identical, you mean the same properties and the properties' ordering/sequence? Or is the ordering of the properties inconsequential? – Ahmed Refaat Feb 25 '19 at 17:24
  • Order shouldn't matter, since JSON fields must be unique; normal hash tables don't have key order. – Doug Stevenson Feb 25 '19 at 17:25
  • Apologies if my original description was confusing, but there is no top-level array; `articles` in this case is a top-level (root?) collection in my database. `relatedArticles`, however, is a small array (with small elements) within every `article` document in the `articles` collection. – Ahmed Refaat Feb 25 '19 at 17:28
  • 1
    Then you can search relatedArticles for exact contents. You must provide both id and title to make that work. – Doug Stevenson Feb 25 '19 at 17:29
  • (In the future, it's best not to show documents of a collection using sqaure bracket array syntax. Collections are not arrays.) – Doug Stevenson Feb 25 '19 at 17:30