Filter a collection group query in FireStore

岁酱吖の 提交于 2020-06-16 19:13:45

问题


I have a database structure as follows (simplified for purposes of this question):

Collection: item_A
    -> Document: params = {someParameter: "value"}
    -> Document: user_01
        -> Sub-collection: orders_item_A
            -> Document: order_AA = {type: "A1", address: {pincode: "000000", city:"Paris"}
            -> Document: order_AB = {type: "A2", address: {pincode: "111111", city:"London"}
            ...
    -> Document: user_02
        -> Sub-collection: orders_item_A
            -> Document: order_AC = {type: "A1", address: {pincode: "222222", city:"Berlin"}
            -> Document: order_AD = {type: "A1", address: {pincode: "333333", city:"Paris"}
            ...

I am using a collection group query to retrieve all the orders under "item_A" (across all users). I am able to get this to work via:

let orders = [];
await firestore()
    .collectionGroup("orders_item_A")
    .get()
    .then(function (querySnapshot) {
        querySnapshot.forEach(function (doc) {
            console.log(doc.id, ' => ', doc.data());
            orders.push(doc.data());
        });
    })

But now I need to refine the above to be able to filter for orders from specific cities (e.g. Paris). So I tried adding a 'where' clause as follows:

let orders = [];
await firestore()
    .collectionGroup("orders_item_A")
    .where("address.city", "==", "Paris")
    .get()
    .then(function (querySnapshot) {
        querySnapshot.forEach(function (doc) {
            console.log(doc.id, ' => ', doc.data());
            orders.push(doc.data());
        });
    })

But this fails, and I get the following message:

Error: [Error: [firestore/failed-precondition] Operation was rejected because the system is not in a state required for the operation's execution. Ensure your query has been indexed via the Firebase console.]

I have already set up a composite index on my FireStore database with the following details:

Collection ID = orders_item_A

Fields indexed = address.city Ascending type Ascending

Status = Enabled

I am not sure what I am doing incorrectly. I wondered if the problem is with using an object property within the 'where' clause (which should not be the problem). So I also tested with a simpler query such as:

.where("type", "==", "A1")

But this too failed. What am I doing wrong?


回答1:


I figured out the problem. My mistake was apparently in having made a "Composite" index (as I mentioned in the question) as it was the opening page on clicking "Indexes". I should have made a "Single field" index:

After deleting my existing composite index, I made a new "single field" index with details as:

Click 'Next' and on the next screen, "enable" one of the options under 'Collection group scope' (I chose Ascending):

It is important to do the above, or else the query will not work. And then everything worked as expected, with my original code:

let orders = [];
await firestore()
    .collectionGroup("orders_item_A")
    .where("address.city", "==", "Paris")
    .get()
    .then(function (querySnapshot) {
        querySnapshot.forEach(function (doc) {
            console.log(doc.id, ' => ', doc.data());
            orders.push(doc.data());
        });
    })

Note: If you happen to delete a particular "index", it takes some time (upto 10 minutes on some occasions) to be ready. During this period you will get an error if trying to create an index for the same entry. So wait, and try again after some time.



来源:https://stackoverflow.com/questions/62157759/filter-a-collection-group-query-in-firestore

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!