Guarde el subconjunto de la colección MongoDB en otra colección

Tengo un set como tal

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

¿Cómo guardo un subconjunto de esos documentos con la fecha ‘20120105’ en otra colección?

es decir db.subset.save(db.full_set.find({date: "20120105"}));

Aquí está la versión de shell:

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

Nota: A partir de MongoDB 2.6, el marco de agregación permite hacer esto más rápido; ver la respuesta de melan para más detalles.

Como solución más nueva, recomendaría utilizar el marco de Agregación para el problema:

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

Funciona aproximadamente 100 veces más rápido que para Al menos en mi caso. Esto se debe a que toda la interconexión de agregación se ejecuta en el proceso mongod, mientras que una solución basada en find() e insert() debe enviar todos los documentos del servidor al cliente y luego regresar. Esto tiene una penalización de rendimiento, incluso si el servidor y el cliente están en la misma máquina.

En realidad, hay un equivalente de insert into ... select from de SQL insert into ... select from en MongoDB. Primero, convierte varios documentos en una matriz de documentos; luego insertas la matriz en la colección objective

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

La solución más general es esta:

Haz uso de la agregación (respuesta dada por @melan):

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

Esto funciona incluso cuando hay documentos en “subconjunto” antes de la operación y desea conservar esos documentos “antiguos” y simplemente insertar un nuevo subconjunto en él.

Se debe tener cuidado, porque el copyTo() reemplaza los documentos con el mismo _id .

No hay un equivalente directo de la insert into ... select from ... de SQL insert into ... select from ...

Tienes que encargarse tú mismo. Obtenga documentos de su interés y guárdelos en otra colección.

Puedes hacerlo en el shell, pero usaría un pequeño script externo en Ruby. Algo como esto:

 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 Toma los documentos devueltos por la canalización de agregación y los escribe en una colección especificada.

  • La operación $ out crea una nueva colección en la base de datos actual si aún no existe.
  • La colección no está visible hasta que la agregación se complete.
  • Si la agregación falla, MongoDB no crea la colección.

Sintaxis:

 { $out: "" } 

Ejemplo A libros de colección contiene los siguientes documentos:

 { "_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 } 

La siguiente operación de agregación pivota los datos en la colección de libros para agrupar los títulos por autores y luego escribe los resultados en la colección de autores.

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

Después de la operación, la colección de autores contiene los siguientes documentos:

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

En la pregunta, use la siguiente consulta y obtendrá una nueva colección llamada ‘col_20120105’ en su base de datos

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