Tengo dos colecciones: col1 y col2 en la misma base de datos. Esas colecciones contienen documentos que tienen dos campos: _id y arr. Estoy tratando de encontrar coincidencias para el mismo _id y cada vez que se encuentra una coincidencia, me gustaría concatenar las dos matrices arr.
En col1 tengo el siguiente documento
{'_id': 'shalom', 'arr': [1, 2, 3]}En col2 tengo el siguiente documento
{'_id': 'shalom', 'arr': [4, 5, 6]}Quiero crear un nuevo documento en col1 que se verá como
{'_id': 'shalom', 'arr': [1, 2, 3, 4, 5, 6]}Lo que hice hasta ahora (que no funciona) es
merge_query = {'into': col1, 'on': '_id', 'whenMatched': [ {'$addFields': { 'processed_words': {'$add': ['$arr', '$$new.arr']}}}], 'whenNotMatched': 'insert'} col2.aggregate([{'$project': project_query}, {'$merge': merge_query}])Al ejecutar esto obtengo la siguiente excepción
pymongo.errors.OperationFailure: $add only supports numeric or date types, not array, full error: {'ok'...Entonces parece que ya casi está allí, solo necesita poder admitir la concatenación de matrices.
Puede usar $concatArrays o $setUnion de esta manera:
Primero $lookup para obtener la otra matriz de colección y cree una nueva matriz 'auxiliar' llamada newArray .
Aquí, $lookup devuelve una matriz, por lo que es necesario usar $arrayElementAt para obtener la primera (y única) posición.
Luego use $concatArrays o $setUnion para concatenar campos y eliminar la matriz 'auxiliar'.
db.coll1.aggregate([ { "$lookup": { "from": "coll2", "localField": "_id", "foreignField": "_id", "as": "newArray" } }, { "$set": { "newArray": { "$arrayElemAt": [ "$newArray", 0 ] } } }, { "$set": { "arr": { "$setUnion": [ "$arr", "$newArray.arr" ] } } }, { "$project": { "newArray": 0 } } ])Ejemplo aquí
He comprobado esto y funciona bien. Cuando une matrices, necesita usar $concatArrays . La operación $add es para números que lo sumarán, por ejemplo (1+1=2)
db.col2.aggregate([ { $merge:{'into': "col1", 'on': '_id', 'whenMatched': [ {'$addFields': { 'processed_words': {'$concatArrays': ['$arr', '$$new.arr']}}}], 'whenNotMatched': 'insert' } } ])