Можно ли 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}})
Надеюсь, это вам полезно.
Удачи !