Enregistrer le sous-ensemble de la collection MongoDB dans une autre collection

J’ai un set comme ça

{date: 20120101} {date: 20120103} {date: 20120104} {date: 20120005} {date: 20120105} 

Comment enregistrer un sous-ensemble de ces documents avec la date ‘20120105’ dans une autre collection?

c’est-à-dire db.subset.save(db.full_set.find({date: "20120105"}));

Voici la version du shell:

 db.full_set.find({date:"20120105"}).forEach(function(doc){ db.subset.insert(doc); }); 

Remarque: à partir de MongoDB 2.6, la structure d’agrégation permet de le faire plus rapidement; voir la réponse de melan pour plus de détails.

En tant que solution plus récente, je conseillerais d’utiliser le cadre d’agrégation pour le problème:

db.full_set.aggregate([ { $match: { date: "20120105" } }, { $out: "subset" } ]);

Cela fonctionne environ 100 fois plus vite que pour au moins dans mon cas. Cela est dû au fait que tout le pipeline d’agrégation s’exécute dans le processus mongod, alors qu’une solution basée sur find() et insert() doit envoyer tous les documents du serveur au client, puis de nouveau. Cela présente une pénalité de performance, même si le serveur et le client sont sur le même ordinateur.

En fait, il existe un équivalent de l’ insert into ... select from de SQL insert into ... select from dans MongoDB. Tout d’abord, vous convertissez plusieurs documents en un tableau de documents. puis vous insérez le tableau dans la collection cible

 db.subset.insert(db.full_set.find({date:"20120105"}).toArray()) 

La solution la plus générale est la suivante:

Utilisez l’agrégation (réponse donnée par @melan):

 db.full_set.aggregate({$match:{your query here...}},{$out:"sample"}) db.sample.copyTo("subset") 

Cela fonctionne même lorsqu’il y a des documents dans “sous-ensemble” avant l’opération et que vous souhaitez conserver ces “anciens” documents et y insérer simplement un nouveau sous-ensemble.

Il faut faire attention, car la commande copyTo() remplace les documents par le même _id .

Il n’y a pas d’équivalent direct de l’ insert into ... select from ... de SQL insert into ... select from ...

Vous devez en prendre soin vous-même. Récupère des documents intéressants et les sauvegarde dans une autre collection.

Vous pouvez le faire dans le shell, mais j’utiliserais un petit script externe dans Ruby. Quelque chose comme ça:

 require 'mongo' db = Mongo::Connection.new.db('mydb') source = db.collection('source_collection') target = db.collection('target_collection') source.find(date: "20120105").each do |doc| target.insert doc end 

$ out Prend les documents renvoyés par le pipeline d’agrégation et les écrit dans une collection spécifiée.

  • L’opération $ out crée une nouvelle collection dans la firebase database actuelle s’il n’en existe pas déjà une.
  • La collection n’est pas visible tant que l’agrégation n’est pas terminée.
  • Si l’agrégation échoue, MongoDB ne crée pas la collection.

Syntaxe:

 { $out: "" } 

Exemple Un recueil contient les documents suivants:

 { "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 } { "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 } { "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 } { "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 } { "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 } 

L’opération d’agrégation suivante fait pivoter les données dans la collection de livres pour que les titres soient regroupés par auteurs, puis écrit les résultats dans la collection d’auteurs.

 db.books.aggregate( [ { $group : { _id : "$author", books: { $push: "$title" } } }, { $out : "authors" } ] ) 

Après l’opération, la collection d’auteurs contient les documents suivants:

 { "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] } { "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] } 

Dans la question posée, utilisez la requête suivante et vous obtiendrez une nouvelle collection nommée ‘col_20120105’ dans votre firebase database

  db.products.aggregate([ { $match : { date : "20120105" } }, { $out : "col_20120105" } ]);