Можно ли mongodump последние записи "x" из коллекции?

Можете ли вы использовать mongodump для выгрузки последних "х" документов из коллекции? Например, в оболочке mongo вы можете выполнить:

db.stats.find().sort({$natural:-1}).limit(10);

Доступна ли эта возможность для mongodump?

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

Заранее спасибо,

Майкл

Ответ 1

mongodump не полностью раскрывает интерфейсы курсора. Но вы можете обойти его, используя параметр --query. Сначала получите общее количество документов коллекции

db.collection.count()

Скажем, есть 10000 документов, и вы хотите последние 1000. Чтобы сделать это, получите идентификатор первого документа, который вы хотите сбросить.

db.collection.find().sort({_id:1}).skip(10000 - 1000).limit(1)

В этом примере идентификатор был "50ad7bce1a3e927d690385ec". Теперь вы можете mongodump с этой информацией, чтобы сбросить все документы a с более высоким или равным id.

$ mongodump -d 'your_database' -c 'your_collection' -q '{_id: {$gte: ObjectId("50ad7bce1a3e927d690385ec")}}'

UPDATE Новые параметры --limit и --skip были добавлены в mongoexport, вероятно, будут доступны в следующей версии инструмента: https://github.com/mongodb/mongo/pull/307

Ответ 2

mongodump поддерживает оператора --query. Если вы можете указать свой запрос в виде json-запроса, вы сможете это сделать.

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

Ответ 3

Построение ответа Mic92, чтобы получить самые последние 1000 предметов из коллекции:

Найдите _id 1000-го самого последнего элемента:

db.collection.find('', {'_id':1}).sort({_id:-1}).skip(1000).limit(1)

Это будет что-то вроде 50ad7bce1a3e927d690385ec.

Затем передайте этот _id в запросе mongodump:

$ mongodump -d 'your_database' -c 'your_collection' -q '{_id: {$gt: ObjectId("50ad7bce1a3e927d690385ec")}}'

Ответ 4

Я играл с аналогичным требованием (используя mongodump), где я хотел выполнить последовательное резервное копирование и восстановление. Я бы взял дамп из последней сохраненной метки времени. Я не смог пройти через --query '{TIMESTAMP: {$ gte: $ stime, $ lt: $ etime}}'

Некоторые моменты, которые следует учитывать: 1) использовать одиночную кавычку вместо двойного 2) не избегать $ или ничего 3) замена $ stime/$ etime на реальные числа сделает работу запроса 4) проблема, с которой я столкнулся, заключалась в получении $ stime/$ etime разрешено до того, как mongodump выполнит себя под -x, он показал как + eval mongodump --query '{TIMESTAMP: {\ $ gte: $ utc_stime,\$ lt: $ utc_etime}}' ++ mongodump --query '{TIMESTAMP: $ gte: 1366700243} '' {TIMESTAMP: $ lt: 1366700253} '

Черт, проблема была очевидна. запрос преобразуется в два условных выражения.

Решение сложное, и я получил его после повторных испытаний.... побег {и} т.е. использование {..}. Это устраняет проблему.

Ответ 5

попробуй это:

NUM=10000    
doc=selected_doc
taskid=$(mongo 127.0.0.1/selected_db -u username -p password --eval "db.${doc}.find({}, {_id: 1}).sort({_id: -1}).skip($NUM).limit(1)" |  grep -E  -o '"[0-9a-f]+"')
mongodump --collection $doc  --db selected_db --host 127.0.0.1 -u username -p password -q "{_id: {\$gte: $taskid}}" --out ${doc}.dump

Ответ 6

_id -based подходы могут не работать, если вы используете пользовательские _id для вашей коллекции (например, возвращаемый 3 партии API). В этом случае вы должны зависеть от createdAt или эквивалентного поля:

COL="collectionName"
HOW_MANY=10000

DATE_CUTOFF=$(mongo <host, user, pass...> dbname --quiet \
--eval "db.$COL.find({}, { createdAt: 1 }).sort({ createdAt: -1 }).skip($HOW_MANY).limit(1)"\
| grep -E -o '(ISODate\(.*?\))')

echo "Copying $HOW_MANY items after $DATE_CUTOFF..."

mongodump <host, user, pass...> -d dbname -c ${COL}\
-q "{ createdAt: { \$gte: $DATE_CUTOFF} }" --gzip

Ответ 7

Функция find() имеет необязательный второй параметр, который указывает, какие ключи должны быть возвращены. Специальный оператор "$ slice" может использоваться для возврата подмножества элементов для ключа массива.

Например, если мы хотим вернуть первые 10 комментариев в блоге (например), мы можем сделать следующее:

db.blog.posts.find(criteria, {"comments" : {"$slice" : 10}})

В качестве альтернативы, если мы хотим вернуть последние 10 комментариев, мы могли бы использовать -10:

db.blog.posts.find(criteria, {"comments" : {"$slice" : -10}})

Надеюсь, это вам полезно.

Удачи !