繁体   English   中英

Firebase 基于过滤器的 Firestore 查询

[英]Firebase Firestore Query based on filters

假设我在 Cloud Firestore 中收集了 2000 个文档,其中包含字段 ID、年龄、位置。

在客户端(nodejs),我有 50 个 id,只想对这 50 个 id 在 firestore 上执行查询,并且应该满足 age>25,location=chicago 等条件。 我不想阅读所有 50 份文件。 想从这50个id中读取满足我说的条件的文档(结果文档可能少于50个)试图减少读取操作。 是否有可能做到这一点? 查看我在操作员中看到的文档,但我的理解是它只支持 10 个比较值。 是否可以按我的要求查询?

创建文档时,如果可以进行查询,我可以将 documentId 调整为字段 id。

根据您的要求,您仍然可以使用如下代码的比较值:

Firebase Web 版本 8:

db.collection("users")
    .where("age", ">", "25")
    .where("location", "==", "chicago")
    .get()
    .then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
            // doc.data() is never undefined for query doc snapshots
            console.log(doc.id, " => ", doc.data());
        });
    })
    .catch((error) => {
        console.log("Error getting documents: ", error);
    });

Firebase Web 版本 9:

const q = query(collection(db, "users"), where("age", ">", "25"), where("location", "==", "chicago");

const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
  // doc.data() is never undefined for query doc snapshots
  console.log(doc.id, " => ", doc.data());
});

您可以使用这些运算符( <<=>>= )尽可能多地使用比较值。 通过使用多个where查询,它为您提供了一个具有逻辑AND查询的查询语句。 唯一的限制是针对这些文档中声明的逻辑OR查询:

Cloud Firestore 对逻辑OR查询提供有限支持。 in 和 array-contains-any 运算符支持单个字段上最多 10 个相等 (==) 或 array-contains 条件的逻辑OR 对于其他情况,为每个 OR 条件创建一个单独的查询并将查询结果合并到您的应用程序中。


更新:

如果要同时查询50个文档。 您可以使用FieldPath.documentID()和“IN”查询来查询它。 请参阅下面的代码:

const docArray = [
// Array of Document IDs.
];

db.collection("users")
    .where(firebase.firestore.FieldPath.documentId(), 'in', docArray)
    .where("age", ">", "25")
    .where("location", "==", "chicago")
    .get()
    .then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
            // doc.data() is never undefined for query doc snapshots
            console.log(doc.id, " => ", doc.data());
        });
    })
    .catch((error) => {
        console.log("Error getting documents: ", error);
    });

正如我在之前的回答中所述,这仅在数组少于 10 个项目( Firestore 限制)时有效。 如果您需要更多,则必须将 ID 批处理为更小的 arrays 并执行多个查询。 检查我在下面写的代码:

// Consists of 11 values
const docArray = [
    '5fKmta1jgEiCQBZvSJ3Y',
    'BubAGhg6IZbnzU70wdPf',
    'FVEq9trqF2Hy8ROsAjeW',
    'Nhz0pF2z3zw3aBcmnpqs',
    'TYYDYyIiyhVuWp91h7OS',
    'VDDiUGKkGnwrdo8jmDpb',
    'VXnXEuNfrhUAM8UbZ2AH',
    'XukTkr4XBey3yqAvFa3d',
    'cSNI1NgHP8OEsDY66RBw',
    'eCPc9F1bpS1qXD9WGKE2',
    'eHdKQPhE7snnRjoWJzBK'
];
const chunkedArray = [];
const resArray = [];
var promises = [];

// Firestore query limit
size = 10;

for(var i = 0; i < docArray.length; i += size) {
chunkedArray.push(docArray.slice(i, i+size));
}

chunkedArray.forEach((chunked) => {
    promises.push(
        db.collection("users")
            .where(firebase.firestore.FieldPath.documentId(), 'in', chunked)
            .where("age", ">", "25")
            .where("location", "==", "chicago")
            .get()
            .then((querySnapshot) => {
                querySnapshot.forEach((doc) => {
                    resArray.push(doc.data());
                });
            })
            .catch((error) => {
                console.log("Error getting documents: ", error);
            })
    );
})

Promise.all(promises).then(() => 
    // Returns merged data from forEach
    console.log(resArray)
);

您也可以简单地迭代 ID,并分别对每个文档进行 get()。 看下面的示例代码:

docArray.forEach((docId) => {
    promises.push(
        db.collection("users")
            .where(firebase.firestore.FieldPath.documentId(), '==', docId)
            // .where("age", ">", "25")
            // .where("location", "==", "chicago")
            .get()
            .then((querySnapshot) => {
                querySnapshot.forEach((doc) => {
                    resArray.push(doc.data());
                });
            })
            .catch((error) => {
                console.log("Error getting documents: ", error);
            })
    );
})

Promise.all(promises).then(() => 
    // Returns merged data from forEach
    console.log(resArray)
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM