Necesito ayuda: quiero optimizar esta consulta para que sea más rápida, necesita filtrar por events.eventType:"log" all docs with server:"strong", pero sin etapas separadas de desenrollado y filtrado, tal vez de alguna manera dentro de $reduce etapa para agregar $ filtro.
ejemplo de documento único:
{ server: "strong", events: [ { eventType: "log", createdAt: "2022-01-23T10:26:11.214Z", visitorInfo: { visitorId: "JohnID" } }consulta de agregación actual:
db.collection.aggregate([ { $match: { server: "strong" } }, { $project: { total: { $reduce: { input: "$events", initialValue: { visitor: [], uniquevisitor: [] }, in: { visitor: { $concatArrays: [ "$$value.visitor", [ "$$this.visitorInfo.visitorId" ] ] }, uniquevisitor: { $cond: [ { $in: [ "$$this.visitorInfo.visitorId", "$$value.uniquevisitor" ] }, "$$value.uniquevisitor", { $concatArrays: [ "$$value.uniquevisitor", [ "$$this.visitorInfo.visitorId" ] ] } ] } } } } } } ])resultado esperado, dos listas con un ID de visitante único y una lista de todos los ID de visitante:
[ { "total": { "uniquevisitor": [ "JohnID" ], "visitor": [ "JohnID", "JohnID" ] }} ]
En la consulta de ejemplo, no se agrega ningún filtro para events.eventType:"log", ¿cómo se puede implementar esto sin $unwind?
No estoy seguro de que este enfoque esté más optimizado que el suyo, pero podría ser útil,
$filter para iterar el bucle de events y filtrar por eventType$let declarar events variables y almacenar el resultado de los filtros anterioresvisitor usando la notación de puntos $$events.visitorInfo.visitorIduniquevisitor mediante el uso de la notación de puntos $$events.visitorInfo.visitorId y el operador $setUnion db.collection.aggregate([ { $match: { server: "strong" } }, { $project: { total: { $let: { vars: { events: { $filter: { input: "$events", cond: { $eq: ["$$this.eventType", "log"] } } } }, in: { visitor: "$$events.visitorInfo.visitorId", uniquevisitor: { $setUnion: "$$events.visitorInfo.visitorId" } } } } } } ]) O un enfoque similar sin $let y dos etapas de $project ,
db.collection.aggregate([ { $match: { server: "strong" } }, { $project: { events: { $filter: { input: "$events", cond: { $eq: ["$$this.eventType", "log"] } } } } }, { $project: { total: { visitor: "$events.visitorInfo.visitorId", uniquevisitor: { $setUnion: "$events.visitorInfo.visitorId" } } } } ])