node.js - 如果不存在,则使用“新”字段写入文档,否则合并字段
问题描述
使用 firebase 函数,我每 x 分钟轮询一次 API,以获取我保存的一组项目。假设每个项目看起来像这样:
{ name: "John", id: 1}
如果这是一个新文档,我想将其存储在 firestore 中,并带有一个state
值为“New”的字段:
[1]: { name: "John", state: "New"}
但是,如果我以前看过这个文档(它在具有该 ID 的 Firestore 中),我想更新里面的数据,但保持状态不变,即
前:
[1]: { name: "John", state: "Processed"}
后:
[1]: {name: "UpdatedName", state: "Processed"}
我怎样才能做到这一点?对于已经存在的文档,我可以使用mergeFields
SetOption来实现这一点,因此排除 state 字段 - 但不幸的是,随后到达的全新文档未设置为state: "New"
.
另一种选择是使用firebase检查每个文档是否存在id,但这似乎不太理想并且难以实现(我最终在foreach循环中进行了多个查询)。这大致是我的代码:
const batch = db.batch();
response.data.items.forEach(item => {
const document = {
name: item.name
state: "New"
};
batch.set(
db.collection(collectionPath).doc(item.id),
document,
{
mergeFields: Object.keys(document).filter(
field => field !== 'state'
),
}
);
});
return batch.commit();
解决方案
由于文档的新状态在文档的现有状态(或缺少状态)上,因此您需要在此处执行事务。
let docRef = db.collection(collectionPath).doc(item.id);
let transaction = db.runTransaction(t => {
return t.get(docRef)
.then(doc => {
if (doc.exists()) {
t.update(docRef, { state: "Processed" });
}
else {
t.set(docRef, { name: "John", state: "New" });
}
});
}).then(result => {
console.log('Transaction success!');
}).catch(err => {
console.log('Transaction failure:', err);
});
推荐阅读
- java - Do - 使用 Char (Java) 进行条件循环
- android - 以编程方式将主题添加到 Seekbar 会使 Seekbar 消失
- typescript - 从枚举数组动态生成类型
- osgi - 如何解决 Adobe Experience Manager 中包含组件期间的错误?
- spring - 具有子系统并可动态添加的自定义 Spring Actuator Endpoint
- r - 使用 bind_rows 将命名向量转换为 df
- typescript - Typescript 属性装饰器问题 - 在初始化之前无法访问
- angular - 如何让 Material Calender 的日期选择器过滤器方法与 Observables 一起使用
- npgsql - 其他所有查询都因语法错误而失败
- c++ - C++ 句子回文