Tengo una colección dentro de MongoDB (4.4 pero la versión no es importante para mí) y uno de los valores del documento es una matriz de URL. Habrá varios documentos con varias URL por documento (dentro de la matriz) y algunas de esas URL ya existirán. Me gustaría seleccionar cada documento con la primera aparición de cada URL (la intención es marcarlo como el 'origen'.
Enlace de MongoPlayground para la colección de muestras: https://mongoplayground.net/p/ZAgCqr517-8
{ "title": "story1_first", "isoDate": "2022-01-01T00:00:00.000Z", "links": [ "www.first.com/article1", "www.anotherdomain.com" ] }, { "title": "story1_mention", "isoDate": "2022-01-10T00:00:00.000Z", "links": [ "www.first.com/article1", "www.somesite.com" ] }, { "title": "story2_first", "isoDate": "2022-01-20T00:00:00.000Z", "links": [ "www.newstory.com/article2", "www.anothercompany.com" ] }, { "title": "story2_mention", "isoDate": "2022-01-20T00:00:00.000Z", "links": [ "www.newstory.com/article2", "www.anothercompany.com" ] } ]En este ejemplo, me gustaría que la consulta/agregación devuelva los dos documentos con "primero" en el título, ya que son los documentos que comparten una URL común dentro de los "enlaces" y son los documentos que tienen la fecha más antigua. Similar a cómo un motor de búsqueda clasifica un sitio dependiendo de cuántos otros sitios se vinculan a él.
Puede hacer lo siguiente en una canalización de agregación:
$unwind links para que los documentos estén en el nivel de enlaces$sort on isoDate para obtener el primer documento$group por links para contar entre el grupo y la identificación del primer documento. En su ejemplo, el título se toma como identificador único.$match con el conteo > 1 para obtener un title que comparte el mismo enlace$group para deduplicar el identificador único que encontramos en el paso 3$lookup nuevo el documento original y hacer algunos cosméticos por $replaceRoot db.collection.aggregate([ { "$unwind": "$links" }, { $sort: { isoDate: 1 } }, { $group: { _id: "$links", first: { $first: "$title" }, count: { $sum: 1 } } }, { $match: { count: { $gt: 1 } } }, { $group: { _id: "$first" } }, { "$lookup": { "from": "collection", "localField": "_id", "foreignField": "title", "as": "rawDocument" } }, { "$unwind": "$rawDocument" }, { "$replaceRoot": { "newRoot": "$rawDocument" } } ])Aquí está el parque infantil de Mongo para su referencia.