fix(MongoDB Node): Stop overwriting nested values on update (#15543)

This commit is contained in:
Elias Meire
2025-05-26 11:30:52 +02:00
committed by GitHub
parent b8ee275f0b
commit 3ee15a8331
3 changed files with 119 additions and 11 deletions

View File

@@ -0,0 +1,80 @@
import { prepareItems } from './GenericFunctions';
describe('MongoDB Node: Generic Functions', () => {
describe('prepareItems', () => {
it('should select fields', () => {
const items = [{ json: { name: 'John', age: 30 } }, { json: { name: 'Jane', age: 25 } }];
const fields = ['name'];
const result = prepareItems({ items, fields });
expect(result).toEqual([{ name: 'John' }, { name: 'Jane' }]);
});
it('should add updateKey to selected fields', () => {
const items = [{ json: { name: 'John', age: 30 } }, { json: { name: 'Jane', age: 25 } }];
const fields = ['age'];
const updateKey = 'name';
const result = prepareItems({ items, fields, updateKey });
expect(result).toEqual([
{ name: 'John', age: 30 },
{ name: 'Jane', age: 25 },
]);
});
it('should handle dot notation', () => {
const items = [{ json: { user: { name: 'John' } } }, { json: { user: { name: 'Jane' } } }];
const fields = ['user.name'];
const useDotNotation = true;
const result = prepareItems({ items, fields, updateKey: '', useDotNotation });
expect(result).toEqual([{ user: { name: 'John' } }, { user: { name: 'Jane' } }]);
});
it('should parse dates', () => {
const items = [
{ json: { date: '2023-10-01T00:00:00Z' } },
{ json: { date: '2023-10-02T00:00:00Z' } },
];
const fields = ['date'];
const dateFields = ['date'];
const useDotNotation = false;
const isUpdate = false;
const result = prepareItems({
items,
fields,
updateKey: '',
useDotNotation,
dateFields,
isUpdate,
});
expect(result).toEqual([
{ date: new Date('2023-10-01T00:00:00Z') },
{ date: new Date('2023-10-02T00:00:00Z') },
]);
});
it('should handle updates', () => {
// Should keep dot notation in result to not overwrite the original values
const items = [
{ json: { id: 1, user: { name: 'John', age: 30 } } },
{ json: { id: 2, user: { name: 'Jane', age: 25 } } },
];
const fields = ['user.name'];
const useDotNotation = true;
const isUpdate = true;
const result = prepareItems({
items,
fields,
updateKey: '',
useDotNotation,
dateFields: [],
isUpdate,
});
expect(result).toEqual([{ 'user.name': 'John' }, { 'user.name': 'Jane' }]);
});
});
});

View File

@@ -80,13 +80,21 @@ export function validateAndResolveMongoCredentials(
} }
} }
export function prepareItems( export function prepareItems({
items: INodeExecutionData[], items,
fields: string[], fields,
updateKey = '', updateKey = '',
useDotNotation = false, useDotNotation = false,
dateFields: string[] = [], dateFields = [],
) { isUpdate = false,
}: {
items: INodeExecutionData[];
fields: string[];
updateKey?: string;
useDotNotation?: boolean;
dateFields?: string[];
isUpdate?: boolean;
}) {
let data = items; let data = items;
if (updateKey) { if (updateKey) {
@@ -112,7 +120,7 @@ export function prepareItems(
fieldData = new Date(fieldData as string); fieldData = new Date(fieldData as string);
} }
if (useDotNotation) { if (useDotNotation && !isUpdate) {
set(updateItem, field, fieldData); set(updateItem, field, fieldData);
} else { } else {
updateItem[field] = fieldData; updateItem[field] = fieldData;

View File

@@ -36,7 +36,7 @@ export class MongoDb implements INodeType {
name: 'mongoDb', name: 'mongoDb',
icon: 'file:mongodb.svg', icon: 'file:mongodb.svg',
group: ['input'], group: ['input'],
version: [1, 1.1], version: [1, 1.1, 1.2],
description: 'Find, insert and update documents in MongoDB', description: 'Find, insert and update documents in MongoDB',
defaults: { defaults: {
name: 'MongoDB', name: 'MongoDB',
@@ -248,7 +248,7 @@ export class MongoDb implements INodeType {
? { upsert: true } ? { upsert: true }
: undefined; : undefined;
const updateItems = prepareItems(items, fields, updateKey, useDotNotation, dateFields); const updateItems = prepareItems({ items, fields, updateKey, useDotNotation, dateFields });
for (const item of updateItems) { for (const item of updateItems) {
try { try {
@@ -290,7 +290,14 @@ export class MongoDb implements INodeType {
? { upsert: true } ? { upsert: true }
: undefined; : undefined;
const updateItems = prepareItems(items, fields, updateKey, useDotNotation, dateFields); const updateItems = prepareItems({
items,
fields,
updateKey,
useDotNotation,
dateFields,
isUpdate: nodeVersion >= 1.2,
});
for (const item of updateItems) { for (const item of updateItems) {
try { try {
@@ -329,7 +336,13 @@ export class MongoDb implements INodeType {
this.getNodeParameter('options.dateFields', 0, '') as string, this.getNodeParameter('options.dateFields', 0, '') as string,
); );
const insertItems = prepareItems(items, fields, '', useDotNotation, dateFields); const insertItems = prepareItems({
items,
fields,
updateKey: '',
useDotNotation,
dateFields,
});
const { insertedIds } = await mdb const { insertedIds } = await mdb
.collection(this.getNodeParameter('collection', 0) as string) .collection(this.getNodeParameter('collection', 0) as string)
@@ -370,7 +383,14 @@ export class MongoDb implements INodeType {
? { upsert: true } ? { upsert: true }
: undefined; : undefined;
const updateItems = prepareItems(items, fields, updateKey, useDotNotation, dateFields); const updateItems = prepareItems({
items,
fields,
updateKey,
useDotNotation,
dateFields,
isUpdate: nodeVersion >= 1.2,
});
for (const item of updateItems) { for (const item of updateItems) {
try { try {