Merge Operation¶
MergeOperation đại diện cho stage $merge của MongoDB. Dùng để ghi kết quả của pipeline vào một collection (có thể cùng DB hoặc khác DB), với các tùy chọn khóa on, biến let, và hành vi khi trùng/không trùng tài liệu. Sử dụng builder MergeOperation.builder() (không khởi tạo trực tiếp).
import { MergeOperation } from 'red-aggregation/operations/mergeOperation';
import { ExpressionVariable, Let } from 'red-aggregation/operator/variableOperators/let';
import { WhenDocumentMatch } from 'red-aggregation/operations/mergeOperation/whenDocumentsMatch';
import { WhenDocumentsDontMatch } from 'red-aggregation/operations/mergeOperation/whenDocumentsdontMatch';
Phương thức (Builder)¶
- MergeOperation.builder().intoCollection().build()
- inDatabase()
- on(...idFields)
- let()/exposeVariablesOf()
- whenMatched()/whenDocumentsMatchApply()
- whenNotMatched()
Ghi vào collection¶
MergeOperation.builder()
.intoCollection('users')
.build()
.toDocument(context);
// => { $merge: 'users' }
Ghi vào collection ở DB khác¶
MergeOperation.builder()
.intoCollection('users')
.inDatabase('analytics')
.build()
.toDocument(context);
// => { $merge: { into: { db: 'analytics', coll: 'users' } } }
Đặt trường khóa on¶
MergeOperation.builder()
.intoCollection('users')
.on('email', 'tenantId')
.build()
.toDocument(context);
// => { $merge: { into: 'users', on: ['email', 'tenantId'] } }
Truyền biến vào sub-pipeline (let)¶
const lets = Let.just(
ExpressionVariable.newVariable('temp').forField('price'),
ExpressionVariable.newVariable('discount').forField('discountRate')
);
MergeOperation.builder()
.intoCollection('users')
.let(lets) // hoặc .exposeVariablesOf(lets)
.build()
.toDocument(context);
// => {
// $merge: {
// into: 'users',
// let: { temp: '$price', discount: '$discountRate' }
// }
// }
Hành vi khi trùng/không trùng¶
- Khi trùng (
whenMatched): chọn một trong các hành vi hoặc cập nhật theo pipeline
// Giữ tài liệu hiện có
MergeOperation.builder()
.intoCollection('users')
.whenMatched(WhenDocumentMatch.keepExistingDocument())
.build()
.toDocument(context);
// => { $merge: { into: 'users', whenMatched: 'keepExisting' } }
// Cập nhật bằng pipeline
const pipelineStages = [ { $set: { updatedAt: '$$NOW' } } ];
MergeOperation.builder()
.intoCollection('users')
.whenMatched(WhenDocumentMatch.updateWith(pipelineStages as any))
.build()
.toDocument(context);
// => { $merge: { into: 'users', whenMatched: [ { $set: { updatedAt: '$$NOW' } } ] } }
- Khi không trùng (
whenNotMatched):insert,discard, hoặcfail
MergeOperation.builder()
.intoCollection('users')
.whenNotMatched(WhenDocumentsDontMatch.insertNewDocument())
.build()
.toDocument(context);
// => { $merge: { into: 'users', whenNotMatched: 'insert' } }
Lưu ý sử dụng¶
- Luôn dùng
MergeOperation.builder(); constructor nội bộ yêu cầu nhiều tham số và đã được builder bao gói. intoCollection(name)là bắt buộc và không được rỗng.on(...fields)đặt khóa duy nhất để dò trùng (mặc định là_id).let(...)đưa biến vào trườngletcủa$merge; các biến sẽ được map sang'$field'quacontext.whenMatchedchấp nhận:replace/keepExisting/merge/failhoặcupdateWith(pipeline).whenNotMatchedchấp nhận:insert/discard/fail.MergeOperationkế thừa các field upstream; nếu truyềnlet, các biến sẽ được expose như trường synthetic.