2012-04-04 19 views
12

Tengo una consulta, que selecciona los documentos que se eliminarán. En este momento, los elimino manualmente, así (usando python):Cómo eliminar documentos por consulta de manera eficiente en mongo?

for id in mycoll.find(query, fields={}): 
    mycoll.remove(id) 

Esto no parece ser muy eficiente. ¿Hay una mejor manera?

EDITAR

bien, le debo una disculpa por olvidar mencionar los detalles de la consulta, porque importa. Aquí está el código completo de Python:

def reduce_duplicates(mydb, max_group_size): 
    # 1. Count the group sizes 
    res = mydb.static.map_reduce(jstrMeasureGroupMap, jstrMeasureGroupReduce, 'filter_scratch', full_response = True) 
    # 2. For each entry from the filter scratch collection having count > max_group_size 
    deleteFindArgs = {'fields': {}, 'sort': [('test_date', ASCENDING)]} 
    for entry in mydb.filter_scratch.find({'value': {'$gt': max_group_size}}): 
    key = entry['_id'] 
    group_size = int(entry['value']) 
    # 2b. query the original collection by the entry key, order it by test_date ascending, limit to the group size minus max_group_size. 
    for id in mydb.static.find(key, limit = group_size - max_group_size, **deleteFindArgs): 
     mydb.static.remove(id) 
    return res['counts']['input'] 

Entonces, ¿qué hace? Reduce el número de claves duplicadas como máximo max_group_size por valor clave, dejando solo los registros más recientes. Funciona así:

  1. MR los datos a (key, count) pares.
  2. iterar sobre todos los pares con count > max_group_size
  3. consultar los datos por key, mientras que la clasificación se ascendiendo por la marca de tiempo (la primera más antiguo) y limitar el resultado a los count - max_group_size registros más antiguos
  4. eliminar cada y cada registro encontrado.

Como puede ver, esto lleva a cabo la tarea de reducir los duplicados a un máximo de N registros más nuevos. Entonces, los últimos dos pasos son foreach-found-remove y este es el detalle importante de mi pregunta, que lo cambia todo y tenía que ser más específico al respecto, lo siento.

Ahora, sobre el comando de eliminación de recopilación. Acepta consultas, pero las mías incluyen clasificación y limitación. ¿Puedo hacerlo con eliminar? Bueno, lo he intentado:

mydb.static.find(key, limit = group_size - max_group_size, sort=[('test_date', ASCENDING)]) 

Este intento falla miserablemente. Por otra parte, parece que el tornillo mongo.Observe:

C:\dev\poc\SDR>python FilterOoklaData.py 
bad offset:0 accessing file: /data/db/ookla.0 - consider repairing database 

Ni que decir tiene, que el enfoque foreach-encontrado-eliminar funciona y produce los resultados esperados.

Ahora, espero haber proporcionado suficiente contexto y (con suerte) haber restaurado mi honor perdido.

Respuesta

9

se puede quitar directamente utilizando un lenguaje MongoDB secuencias de comandos:

db.mycoll.remove({_id:'your_id_here'}); 
+0

He editado mi post. – mark

28

Puede utilizar una consulta para eliminar todos los documentos coincidentes

var query = {name: 'John'}; 
db.collection.remove(query); 

Sé cuidadoso, sin embargo, si el número de documentos que coinciden es alto , su base de datos puede ser menos receptiva. A menudo se recomienda eliminar documentos en trozos más pequeños.

Digamos que tiene 100k documentos para eliminar de una colección. Es mejor ejecutar 100 consultas que eliminen documentos 1k cada uno que una consulta que borre todos los documentos 100k.

+0

He editado mi publicación. – mark

+0

'Supongamos que tiene 100k documentos para eliminar de una colección. Es mejor ejecutar 100 consultas que eliminen documentos 1k cada uno que una consulta que elimine todos los documentos de 100k. ¿Cómo podría lograr esto? – Ezequiel

+1

@Ezequiel: uno podría obtener identificadores de todos los documentos que se eliminarán, luego dividirlos en lotes de 1000 y enviar varios comandos de eliminación con el operador '$ in'. –

0

ejecutar esta consulta en cmd

db.users.remove ({ "_id": OBJECTID ("5a5f1c472ce1070e11fde4af")});

Si está usando Node.js escribir este código

User.remove({ _id: req.body.id },, function(err){...}); 
Cuestiones relacionadas