Estoy tratando de hacer un agregado donde me gustaría relacionar elementos de una matriz a otra.
La idea es obtener oraciones relacionadas con términos donde la oración contenga todas las palabras de los elementos de términos. El resultado será un proyecto con todos los campos de texto y un campo personalizado con todos los atributos de los términos.
Aquí está mi primera colección:
db.terms.insertMany([ { "_id" : 1, "items" : ["sun", "day"] }, { "_id" : 2, "items" : ["moon", "night"] }, ])
Y el segundo:
db.texts.insertMany([ { "_id" : 1, "sentence" : ["a beautiful sun makes a bright day", "not usefull here"] }, ])
El agregado de intenciones:
db.texts.aggregate([ {$lookup: { from: "terms", let: { term_items: "$items" }, pipeline: [ { $match: { $expr: { "$sentence": { $all: "$$term_items" } } } } ], as: "term_obj" }}, ]);
Cuando ejecuto este agregado recibo este error:
org.graalvm.polyglot.PolyglotException: el comando falló con el error 168 (InvalidPipelineOperator): 'Expresión no reconocida '$$term_items' en el servidor localhost:27019. La respuesta completa es {"ok": 0.0, "errmsg": "Expresión no reconocida '$$term_items'", "code": 168, "codeName": "InvalidPipelineOperator"}
Otra intención:
db.texts.aggregate([ {$lookup: { from: "terms", let: { term_items: "$items" }, pipeline: [ { $match: { $expr: { $in: ["$$term_items", "$sentence"] } } } ], as: "term_obj" }}, ]);
El error:
org.graalvm.polyglot.PolyglotException: el comando falló con el error 40081 (Ubicación 40081): '$in requiere una matriz como segundo argumento, encontrado: falta' en el servidor localhost: 27019. La respuesta completa es {"ok": 0.0, "errmsg": "$in requiere una matriz como segundo argumento, encontrado: faltante", "code": 40081, "codeName": "Location40081"}
¿Qué me estoy perdiendo aquí?
En la búsqueda existente, está utilizando $items
antes de que tenga un valor. $let
es donde debería asignar $sentence
del documento externo a una variable.
Una posible solución para realizar esta búsqueda:
sentence
items
y prueba con $in
db.texts.aggregate([ {$lookup: { from: "terms", let: {sentences: "$sentence"}, pipeline: [ {$match: { $expr: { $reduce: { initialValue: false, input: { $map: { input: "$$sentences", as: "sentence", in: {$reduce: { input: "$items", initialValue: "true", in: {$and: [ "$$value", {$regexMatch: { regex: "$$this", input: "$$sentence" }} ]} }} } }, in: {$or: ["$$this", "$$value"]} } } }} ], as: "term_obj" }} ])