是否有可能mongodump集合中的最后一个“x”记录?

时间:2011-10-19 22:07:15

标签: mongodb

您可以使用mongodump从集合中转储最新的“x”文档吗?例如,在mongo shell中,您可以执行:

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

mongodump可以使用相同的功能吗?

我想解决方法是将上面的文档转储到一个新的临时集合中并mongodump整个临时集合,但是通过mongodump可以做到这一点很棒。

提前致谢,

迈克尔

7 个答案:

答案 0 :(得分:43)

mongodump未完全公开游标接口。 但您可以使用--query参数解决此问题。 首先获取集合的文档总数

db.collection.count()

假设有10000个文件,你想要最后1000个。 为此,请获取要转储的第一个文档的ID。

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

在此示例中,ID为"50ad7bce1a3e927d690385ec"。 现在,您可以使用此信息提供mongodump,以转储所有具有更高或相同ID的文档。

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

<强>更新 --limit中添加的新参数--skipmongoexport可能会在下一版工具中提供:https://github.com/mongodb/mongo/pull/307

答案 1 :(得分:4)

mongodump supports the --query operator。如果您可以将查询指定为json查询,那么您应该能够做到这一点。

如果没有,那么你运行查询以将记录转储到临时集合然后转储的技巧就可以了。在这种情况下,您可以使用shell脚本自动执行转储,该脚本使用javascript命令调用mongo以执行您想要的操作,然后调用mongodump。

答案 2 :(得分:3)

根据Mic92的答案,从一个系列中获取最新的1000件物品:

找到第1000个最近项目的_id

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")}}'

答案 3 :(得分:1)

我正在玩类似的要求(使用mongodump),我想进行顺序备份和恢复。我会从上次存储的时间戳中获取转储。 我无法通过 - 查询'{TIMESTAMP:{$ gte:$ stime,$ lt:$ etime}}'

有几点需要注意: 1)使用单引号而不是双引号 2)不要逃避$或任何东西 3)用实数替换$ stime / $ etime将使查询起作用 4)我遇到的问题是在mongodump执行之前解决$ stime / $ etime问题    在-x下它显示为 + eval mongodump --query'{TIMESTAMP:{\ $ gte:$ utc_stime,\ $ lt:$ utc_etime}}' ++ mongodump --query'{TIMESTAMP:$ gte:1366700243}''{TIMESTAMP:$ lt:1366700253}'

天啊,问题很明显。查询转换为两个条件。

解决方案很棘手,我在反复试验后得到了它.... 逃避{和}即使用{..}。这解决了这个问题。

答案 4 :(得分:1)

试试这个:

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

答案 5 :(得分:0)

如果您对集合使用自定义的{ var reply = context.Context.Activity.CreateReply(messageText); if (BotDialogHelpers.ExtractMessengerFromDialogContext(context) == BotDialogHelpers.Messengers.Telegram) { GenerateReplyMarkupForTelegram(reply); } await context.Context.SendActivityAsync(reply, token); } /// <summary> /// https://docs.microsoft.com/en-us/azure/bot-service/dotnet/bot-builder-dotnet-channeldata?view=azure-bot-service-3.0 /// https://core.telegram.org/bots/api#message sendMessage reply_markup /// </summary> private void GenerateReplyMarkupForTelegram(IActivity reply) { var replyMarkup = new { reply_markup = new { remove_keyboard = true, } }; var channelData = new { method = "sendMessage", parameters = replyMarkup, }; reply.ChannelData = JObject.FromObject(channelData); } (例如由第三方API返回的),则基于

_id的方法可能无法使用。在这种情况下,您应该依赖_id或等效字段:

createdAt

答案 6 :(得分:-1)

find()函数有一个可选的第二个参数,它指定要返回的键。特殊的“$ slice”运算符可用于返回数组键的元素子集。

例如,如果我们想要在博客集合中返回前10个评论(例如),我们就可以做到这一点:

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

或者,如果我们想要返回最后10条评论,我们可以使用-10:

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

希望这对你有用。

祝你好运!