Можно ли монгодумпировать последние "х" записи из коллекции? - PullRequest
29 голосов
/ 20 октября 2011

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

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

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

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

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

Michael

Ответы [ 7 ]

44 голосов
/ 19 апреля 2013

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

db.collection.count()

Допустим, есть 10000 документов, а вы хотите последнюю 1000. Для этого получите идентификатор первого документа, который вы хотите выгрузить.

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

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

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

ОБНОВЛЕНИЕ Добавлены новые параметры --limit и --skipmongoexport, вероятно, будет доступно в следующей версии инструмента: https://github.com/mongodb/mongo/pull/307

5 голосов
/ 08 сентября 2013

На основе ответа 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 голосов
/ 20 октября 2011

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

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

1 голос
/ 25 мая 2017

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

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
1 голос
/ 24 апреля 2013

Я играл с аналогичным требованием (используя 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}'

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

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

0 голосов
/ 21 января 2019
Подходы

_id могут не работать, если вы используете пользовательский _id для своей коллекции (такой как возвращенный сторонним 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
0 голосов
/ 20 октября 2011

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

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

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

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

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

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

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...