Azure Data Factory中如何阻止指定字段在Upsert时更新?
Cosmos DB NoSQL Upsert时保留
batch字段的实现方案 核心需求:Upsert操作中,新插入文档的batch字段设为当前日期,已有文档更新时保留原batch值。由于AlterRow无法实现部分字段的条件性更新,可通过以下两种方案解决:
方案一:Lookup读取现有文档+字段合并
- 在Data Flow中添加Lookup组件,以文档唯一键(如
id)为关联条件,查询Cosmos DB中已存在的文档。 - 添加Derived Column组件,通过条件逻辑生成
batch字段:- 若Lookup匹配到现有文档(更新场景),直接复用现有文档的
batch值; - 若Lookup无匹配(插入场景),用
currentTimestamp()生成当前日期赋值给batch。
- 若Lookup匹配到现有文档(更新场景),直接复用现有文档的
- 将处理后的数据流送入Cosmos DB Sink,配置为Upsert模式并指定唯一键。
该方案逻辑直观,易调试,但会增加一次读操作,大流量场景需评估性能开销。
方案二:Cosmos DB存储过程实现逻辑下沉
编写存储过程在数据库端完成条件Upsert,避免Data Flow中的额外读操作:
function upsertDocument(doc, batchDate) { const collection = getContext().getCollection(); const requestOptions = { enableUpsert: true }; // 尝试读取目标文档 collection.readDocument(`${collection.getSelfLink()}/docs/${doc.id}`, (err, existingDoc) => { if (err) { // 文档不存在,执行插入并设置batch doc.batch = batchDate; collection.createDocument(collection.getSelfLink(), doc, requestOptions, (err, result) => { if (err) throw err; getContext().getResponse().setBody(result); }); } else { // 文档存在,保留原batch,合并更新字段后替换 doc.batch = existingDoc.batch; collection.replaceDocument(existingDoc._self, doc, requestOptions, (err, result) => { if (err) throw err; getContext().getResponse().setBody(result); }); } }); }
在Data Flow的Sink组件中选择调用存储过程模式,传入待处理文档和当前日期参数即可。
此方案性能更优,但需要具备JavaScript编写能力,存储过程的调试相对复杂。
关键注意事项
- 确保Upsert唯一键(如
id)配置准确,避免匹配错误或重复插入; - 使用
currentTimestamp()时注意时区,按需转换为目标时区的日期格式。
内容的提问来源于stack exchange,提问作者Ícaro Lorran
相关产品推荐
相关产品推荐

