Google Pub/Sub 更新 Firestore 子集合

Google Pub/Sub update Firestore sub collection

我试图每 2 分钟更新一次子集合中的字段。如果时间戳早于 3 分钟,我将字段 "Status" 更改为 "Off"。我有这段代码是有人帮助我的,它适用于一个集合,但我不知道要使用什么集合路径来访问其中包含此子集合的所有文档。

5 分钟后,如果时间戳超过 3 分钟,我希望 "Status" 字段为 "Off"。

const snap = await db.collection("MX") 有效但仅适用于 1 层深度。 userProfiles 中的每个文档都有一个 MX 的子集合。

我试过通配符和几种不同的收集路径。

exports.updateIdle = functions.pubsub.schedule('every 2 minutes').onRun(async () => {

const db = admin.firestore();
// this is what line I am trying to figure out
  const snap = await db.collection("userProfiles") 
    .where("Status", "=", "On")
    .where("Timestamp", "<", admin.firestore.Timestamp.fromMillis(Date.now() - 3 * 60000))
    .get();


  await Promise.all(snap.docs.map(doc => doc.ref.update({Status: 'Off'})));

  console.log('this goes off every two minutes')
}); 

编辑: userProfile -> 每个文档 -> 4 个子集合(MX、员工、设置、日志)

我在 MX 中存储了文档。这些文档将具有状态和时间戳。

我希望此 pub/sub 检查存储在 MX 子集合中的所有文档。

并且如果时间戳是 3-5 分钟前的,并且 Status = On。我想将状态更改为关闭

所以我正在检查所有 MX 子集合。在这种情况下,userProfiles 中有 4 个文档,每个文档中都有一个 MX 子集合。

感谢所有帮助。我希望我能很好地解释这一点。谢谢。

如果您想“更新任何具有旧时间戳的 MX 子集合中的所有文档”,以下应该可以使用 Promise.all():

exports.updateIdle = functions.pubsub.schedule('every 2 minutes').onRun(async () => {

    const db = admin.firestore();

    const querySnapshot = await db.collection("userProfiles") 
        .where("Status", "=", "On")
        .where("Timestamp", "<", admin.firestore.Timestamp.fromMillis(Date.now() - 3 * 60000))
        .get();
    
    const promises = [];
    querySnapshot.forEach(doc => {
        const docRef = doc.ref;
        promises.push(docRef.collection('MX').get());
    });
    
    const snapshotArrays = await Promise.all(promises);
    // snapshotArrays contains an array of arrays of QueryDocumentSnapshots

    const promises1 = [];
    
    snapshotArrays.forEach(snapArray => {
        snapArray.forEach(snap => {
            promises1.push(snap.ref.update({
                Status: "Off"
            }))
        })
    });
    
    return Promise.all(promises1);
    
});

当然,我假设您最初查询 userProfile 带有“timestamp 是旧的”文档是正确的。


根据您的评论更新

我知道要在 MX 文档级别过滤“时间戳已过 3-5 分钟,并且状态 = 开启”。那么下面应该可以工作(我们只是将 where 子句移动到 MX 集合)。但是请注意,在这种情况下,我们阅读了所有 userProfile 个文档(每次阅读都需要阅读标准文档)。

exports.updateIdle = functions.pubsub.schedule('every 2 minutes').onRun(async () => {

    const db = admin.firestore();

    const querySnapshot = await db.collection("userProfiles").get();

    const promises = [];
    querySnapshot.forEach(doc => {
        const docRef = doc.ref;
        promises.push(docRef.collection('MX').where("Status", "=", "On")
        .where("Timestamp", "<", admin.firestore.Timestamp.fromMillis(Date.now() - 3 * 60000)).get());
    });

    const snapshotArrays = await Promise.all(promises);
    // snapshotArrays contains an array of arrays of QueryDocumentSnapshots

    const promises1 = [];

    snapshotArrays.forEach(snapArray => {
        snapArray.forEach(snap => {
            promises1.push(snap.ref.update({
                Status: "Off"
            }))
        })
    });

    return Promise.all(promises1);

});

如果您仍然遇到错误,请尝试不使用 where 子句,如下所示,然后修改您的 where 子句以获得所需的 MX 文档选择。

//....
const querySnapshot = await db.collection("userProfiles").get();

const promises = [];
querySnapshot.forEach(doc => {
    const docRef = doc.ref;
    promises.push(docRef.collection('MX').get());
});
//....