2012-03-14 53 views

Respuesta

46

Aquí está la versión de la shell:

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

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

+5

A partir de [2.2] (http://docs.mongodb.org/manual/reference/method/db.collection.insert/), insertar puede tomar una matriz de documentos, por lo que podría hacer 'var docs =. ..find (...). toArray(); db.coll.insert (docs) '. No he encontrado que el rendimiento sea muy bueno en ninguno de los casos, aunque –

+1

Desafortunadamente [$ out] (https://docs.mongodb.org/manual/reference/operator/aggregation/out/) llegó a Mongo desde la versión [2.6 ] (https://docs.mongodb.org/manual/release-notes/2.6/), no [2.2] (https://docs.mongodb.org/manual/release-notes/2.2 /) – CroWell

4

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

Tiene que encargarse usted 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 
13

En realidad, hay un equivalente de SQL insert into ... select from en MongoDB. Primero, convierte varios documentos en una matriz de documentos; a continuación se inserta la matriz en la colección de destino

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

Como solución más reciente que aconsejaría a utilizar marco de agregación para el problema:

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

funciona cerca de 100 veces más rápido que forEach 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() y insert() debe enviar todos los documentos del servidor al cliente y luego volver. Esto tiene una penalización de rendimiento, incluso si el servidor y el cliente están en la misma máquina.

+0

solo tenga en cuenta que fallará si el resultado de la agregación excede el tamaño máximo del documento (16MB) – c24b

+5

$ out no tiene la limitación habitual en el tamaño del documento, ya que está escribiendo en una colección – Kyrstellaine

+0

Evidencia adicional: Acabo de ejecuté una comparación con mis propios datos y el agregado es aproximadamente 50 veces más rápido que para cada uno. También comparé con mapreduce, y el agregado es aproximadamente 5 veces más rápido. – Luke

7

La solución más general es la siguiente:

uso

Hacer 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 la "subconjunto" antes de la operación y Desea conservar esos documentos "antiguos" e inserte un nuevo subconjunto en él.

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

+0

La explicación de copyTo fue muy útil además. – TheDude

Cuestiones relacionadas