简体   繁体   English

Google Pub/Sub 更新 Firestore 子集合

[英]Google Pub/Sub update Firestore sub collection

I am trying to update a field in a subcollection every 2 minutes.我试图每 2 分钟更新一次子集合中的字段。 I am changing the field "Status" to "Off" if the timestamp is older than 3 minutes old.如果时间戳早于 3 分钟,我会将字段“状态”更改为“关闭”。 I have this code that someone helped me with and It works with a collection but I dont know what collection path to use to access all documents that have this subcollection in them.我有这个代码,有人帮助我使用它,它适用于一个集合,但我不知道使用什么集合路径来访问包含此子集合的所有文档。

After 5 minutes I want the "Status" Field to be "Off" if the timestamp is more than 3 minutes old. 5 分钟后,如果时间戳超过 3 分钟,我希望“状态”字段为“关闭”。

const snap = await db.collection("MX") works but only for 1 layer deep. const snap = await db.collection("MX") 有效但仅适用于 1 层深。 Each document in userProfiles has a subCollection of MX. userProfiles 中的每个文档都有一个 MX 的子集合。

I have tried wildcards and several different collection paths.我尝试过通配符和几种不同的收集路径。

在此处输入图片说明

在此处输入图片说明

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')
}); 

EDIT: userProfile -> each doc -> 4 sub collections (MX, employees, settings, logs)编辑:userProfile -> 每个文档 -> 4 个子集合(MX、员工、设置、日志)

I have documents stored inside of MX.我在 MX 中存储了文档。 These documents will have a Status and a Timestamp.这些文档将具有状态和时间戳。

I want this pub/sub to check all of the documents stored inside of the MX subcollection.我希望此发布/订阅检查存储在 MX 子集合中的所有文档。

And if the timestamp is 3-5 minutes old, and Status = On.如果时间戳是 3-5 分钟,并且 Status = On。 I want to change the Status to Off我想将状态更改为关闭

So I am checking all MX subcollections.所以我正在检查所有 MX 子集合。 In this case there is 4 documents in userProfiles and there is a MX subcollection inside each document.在这种情况下,userProfiles 中有 4 个文档,每个文档中有一个 MX 子集合。

I appreciate any and all help.我感谢任何和所有的帮助。 I hope I am explaining this well enough.我希望我能很好地解释这一点。 Thanks.谢谢。

If you want to "update all docs in any MX subcollection that has an old timestamp" the following should work, using Promise.all() :如果您想“更新具有旧时间戳的任何 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);
    
});

Of course, I make the assumption that your initial query to find the userProfile docs with a " timestamp that is old" is correct.当然,我假设您查找带有“旧timestamp ”的userProfile文档的初始查询是正确的。


Update based on your comment根据您的评论更新

I understand that the filtering on "timestamp is 3-5 minutes old, and Status = On" is to be done at the level of the MX documents.我知道“时间戳是 3-5 分钟,并且状态 = 开”的过滤将在 MX 文档级别完成。 The following should work then (we just move the where clauses to the MX collections).下面应该工作(我们只是将where子句移动到MX集合)。 Note however that in this case we read all the userProfile documents (each read costing a standard document read).但是请注意,在这种情况下,我们读取了所有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);

});

If you still encounter errors, try without the where clauses as follows, and refien your where clauses in order to get the desired MX documents selection.如果您仍然遇到错误,请尝试不使用 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());
});
//....

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

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