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í:
- MR los datos a
(key, count)
pares. - iterar sobre todos los pares con
count > max_group_size
- 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 loscount - max_group_size
registros más antiguos - 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.
He editado mi post. – mark