在FireStore中过滤收集组查询 [英] Filter a collection group query in FireStore
问题描述
我具有如下数据库结构(出于这个问题的目的而简化):
集合:item_A->文档:params = {someParameter:值"}}->文件:user_01->子集合:orders_item_A->文件:order_AA = {类型:"A1",地址:{密码:"000000",城市:巴黎"}->文件:order_AB = {类型:"A2",地址:{密码:"111111",城市:伦敦"}...->文件:user_02->子集合:orders_item_A->文件:order_AC = {类型:"A1",地址:{密码:"222222",城市:柏林"}->文件:order_AD = {类型:"A1",地址:{密码:"333333",城市:巴黎"}...
我正在使用集合组查询来检索"item_A"下的所有订单.(针对所有用户).我可以通过以下方式使它起作用:
让订单= [];等待firestore().collectionGroup("orders_item_A").得到().then(function(querySnapshot){querySnapshot.forEach(function(doc){console.log(doc.id,'=>',doc.data());orders.push(doc.data());});})
但是现在我需要完善上述内容,以便能够过滤来自特定城市(例如巴黎)的订单.因此,我尝试如下添加"where"子句:
让订单= [];等待firestore().collectionGroup("orders_item_A").where("address.city","==",巴黎").得到().then(function(querySnapshot){querySnapshot.forEach(function(doc){console.log(doc.id,'=>',doc.data());orders.push(doc.data());});})
但这失败了,我收到以下消息:
错误:[错误:[firestore/failed-precondition]操作被拒绝,因为系统未处于执行操作所需的状态.确保您的查询已通过Firebase控制台建立索引.]
我已经在FireStore数据库上设置了具有以下详细信息的复合索引:
收款ID = orders_item_A
索引的字段= address.city升序类型升
状态=启用
我不确定我做错了什么.我想知道问题是否在于在'where'子句(
删除现有的综合索引后,我创建了一个新的单字段"索引,其详细信息为:
单击下一步",然后在下一个屏幕上,启用"收藏组范围"下的一个选项(我选择了升序"):
执行上述操作很重要,否则查询将无法进行.然后一切正常,使用我的原始代码:
让订单= [];等待firestore().collectionGroup("orders_item_A").where("address.city","==",巴黎").得到().then(function(querySnapshot){querySnapshot.forEach(function(doc){console.log(doc.id,'=>',doc.data());orders.push(doc.data());});})
注意:如果您碰巧要删除特定的索引",则需要花费一些时间(有时最多需要10分钟)来准备.在此期间,如果尝试为同一条目创建索引,则会收到错误消息.因此,请稍等片刻,然后重试.
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?
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.
这篇关于在FireStore中过滤收集组查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!