mongodump, а затем удалить: не точно такое же количество записей

Я использую сценарий ткани для вывода данных с удаленного сервера mongodb на свой локальный компьютер, а затем хочу удалить эти данные с удаленного компьютера. Сейчас я делаю это в два этапа, и хотя я понимаю, что могут существовать более изящные методы еще несколько дней, я хочу продолжать в том же духе. Вот фрагмент функции Python, которую я запускаю как потрясающую задачу.

from __future__ import with_statement
from fabric.api import *
from fabric.contrib.console import confirm
import datetime
import dateutil.relativedelta

def dump_mydb():
    print "********************************"
    print "Starting the dump process"
    print "********************************"
    d = datetime.datetime.today()
    d2 = d - dateutil.relativedelta.relativedelta(months=1)
    end_date = datetime.datetime(d2.year, d2.month, d2.day)
    print end_date
    before_time = int(end_date.strftime("%s")) * 1000 

    temp = datetime.datetime.today()
    temp2 = datetime.datetime(temp.year, temp.month, temp.day)
    local_folder = str(temp2).split(" ")[0]
    local("mongodump --host x.x.x.x --port 27017 --collection my_collection --db my_db -q '{fetched_date :{$lte: Date(" + str(before_time) + ")}}'")
    local("mkdir ../dump_files/store/" + local_folder)
    local("cp -r dump ../dump_files/store/" + local_folder)
    local("rm -rf dump")
    print "********************************"
    print "Data before one month from today is dumped at - ../dump_files/store/" + local_folder
    print "********************************"

Если этот скрипт выполняется сегодня (14 февраля 2014 г., IST), то он ищет все документы, в которых значение «fetched_date» (обычный объект ISODate с указанием даты и времени) меньше, чем равно 14.01.2014 00:00. :00. И эти сценарии выполняются нормально.


Проблема


Когда этот скрипт выполняется, мы видим, что он выгружает X объектов (документов) на мою локальную машину. Но когда мы запускаем этот запрос в удаленной оболочке mongo

{"fetched_date":{"$lte": ISODate("2014-01-14T00:00:00.00Z")}}

Это дает нам другое количество записей. что больше, чем X. Это означает, что мы не можем удалить все записи, соответствующие этому запросу, потому что некоторые из них не были сброшены на мою локальную машину. Я не понимаю, как это возможно, поскольку я конвертирую ту же дату в мс, а затем запускаю запрос в mongodump.

Кто-нибудь может мне помочь, пожалуйста?

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация. Спасибо.


person SRC    schedule 14.02.2014    source источник


Ответы (1)


Я полагаю, что вы столкнулись с той же проблемой, что и я, когда db.collection.find({...}).count() может пересчитать. Согласно подробностям в справочной документации для count() , если вы находитесь в сегментированном кластере, переносимые записи учитываются дважды. (Спасибо GothAlice на канале IRC за то, что указали мне на это!)

Если это ваша проблема, вы можете использовать структуру агрегации, чтобы получить точный подсчет, который должен совпадать с подсчетом, который вы видели в mongodump:

db.collection.aggregate([
      { $match: {"fetched_date":{"$lte": ISODate("2014-01-14T00:00:00.00Z")}} },
      { $group: { _id: null, count: { $sum: 1 } } }
])
person Kyrstellaine    schedule 02.12.2014
comment
Подсчет записей в базе данных трудно выполнить точно и быстро. Используются ярлыки, и эти ярлыки действительно могут привести к ошибочным подсчетам. В случае сегментирования количество будет равно или больше, чем фактическое количество записей. В других ситуациях (например, при выполнении множественных обновлений или множественных удалений) подсчет может быть неправильным по-разному. Данный агрегат будет точным, но только если данные находятся в состоянии покоя (без обновлений/вставок). - person amcgregor; 03.12.2014