web-dev-qa-db-fra.com

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

J'ai un ensemble comme si

{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?

i.e db.subset.save(db.full_set.find({date: "20120105"}));

50
SemperFly

Voici la version Shell:

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

Remarque: à partir de MongoDB 2.6, le cadre d'agrégation permet de le faire plus rapidement. voir la réponse de Melan pour plus de détails.

55
Eve Freeman

En réalité, il existe un équivalent du insert into ... select from de SQL dans MongoDB. Tout d'abord, vous convertissez plusieurs documents en un tableau de documents; alors vous insérez le tableau dans la collection cible

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

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

Utiliser 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 le "sous-ensemble" avant l'opération et que vous souhaitez conserver ces "anciens" documents et y insérer un nouveau sous-ensemble.

Vous devez faire attention car la commande copyTo() remplace les documents avec le même _id.

11
antonimmo

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

Vous devez en prendre soin vous-même. Récupérez des documents d'intérêt et enregistrez-les dans une autre collection.

Vous pouvez le faire dans le shell, mais j'utiliserais un petit script externe en 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
3
Sergio Tulentsev

Mongodb a un agrégat avec l'opérateur $ out qui permet de sauvegarder un sous-ensemble dans une nouvelle collection. Voici les détails: 

$ 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 base de données actuelle, s'il n'en existe pas déjà une. 
  • La collection n'est visible que lorsque l'agrégation est terminée. 
  • Si l'agrégation échoue, MongoDB ne crée pas la collection.

Syntaxe:

{ $out: "<output-collection>" }

Exemple Un recueil de collections 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 de la collection de livres pour regrouper les titres par auteur, 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 authors 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 aurez une nouvelle collection nommée 'col_20120105' dans votre base de données

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