2014-08-28 61 views
14

首先,我对mongodb很陌生。这是我的问题,我一直无法找到解决方案。遍历所有Mongo收藏并执行查询

比方说,我有3个不同的集合。

mongos> show collections 
collectionA 
collectionB 
collectionC 

我希望创建一个遍历IND该数据库中所有集合的脚本,发现在这些藏品最后插入的时间戳。这里是mongos里面的工作。

var last_element = db.collectionA.find().sort({_id:-1}).limit(1); 
printjson(last_element.next()._id.getTimestamp()); 
ISODate("2014-08-28T06:45:47Z") 

1.问题(遍历所有集合)

是否有可能对某事物。喜欢。

var my_collections = show collections; 
my_collections.forEach(function(current_collection){ 
    print(current_collection); 
}); 

问题在这里,my_collections的任务不起作用。我收到SyntaxError: Unexpected identifier。我需要引用'show'语句吗?它甚至有可能吗?

2.问题(存储集合中的JS VAR)

我可以通过执行此替代方法问题1:

var my_collections = ["collectionA", "collectionB", "collectionC"]; 
my_collections.forEach(function(current_collection){ 
    var last_element = db.current_collection.find().sort({_id:-1}).limit(1); 
    print(current_collection); 
    printjson(last_element.next()._id.getTimestamp()); 
}); 

last_element.next()产生以下错误:

error hasNext: false at src/mongo/shell/query.js:124

看来last_element没有正确保存。

关于我在做什么的任何建议是错误的?


UPDATE

尼尔斯的答案使我这个解决方案。除了他的代码,我不得不检查函数getTimestamp是否真的存在。对于某些“虚拟”集合,似乎没有_id属性。

db.getCollectionNames().forEach(function(collname) { 
    var last_element = db[collname].find().sort({_id:-1}).limit(1); 
    if(last_element.hasNext()){ 
     var next = last_element.next(); 
     if(next._id !== undefined && typeof next._id.getTimestamp == 'function'){ 
      printjson(collname + " >> "+next._id.getTimestamp()); 
     }else{ 
      print(collname + " undefined!! (getTimestamp N/A)") 
     } 
    } 
}); 
+1

只是在这里澄清。 '.getTimeStamp()'会在这里失败的唯一原因是你在每个文档的主键“_id”字段中实际上没有“ObjectId”。你应该真的看看这个,好像MongoDB会“允许”你在字段中混合类型,因为它是“无模式的”,你不应该把它作为一般的做法,而应该真正地纠正这个问题发生这种情况可以使条目保持一致。 – 2014-09-01 11:11:30

+0

感谢您的通知!如前所述,我对mongo非常陌生,来自关系数据库背景。 我还不确定这些集合是如何创建的,也不知道为什么他们没有ObjectID。正如你所说,我需要纠正这一点,并需要了解为什么和如何。谢谢! – cb0 2014-09-01 20:28:32

回答

25

还有就是db.getCollectionNames()的辅助方法,这是否适合你。然后,您可以实现您的代码:

db.getCollectionNames().forEach(function(collname) { 
    // find the last item in a collection 
    var last_element = db[collname].find().sort({_id:-1}).limit(1); 
    // check that it's not empty 
    if (last_element.hasNext()) { 
     // print its timestamp 
     printjson(last_element.next()._id.getTimestamp()); 
    } 
}) 

你可能还需要一个.hasNext()检查在那里,以应付可能的空集合。

+0

我想说,在所有调用都是同步的shell环境中,这只是安全的。该解决方案在异步驱动程序环境中存在风险(快速连续执行许多并行查询)。 – zamnuts 2014-09-01 07:46:37

+0

@zamnuts有很多方法可以在异步环境中安全地处理列表和数据流。你只需要知道回调来宣布每个迭代。如果你对此不确定,那么你总是可以提出一个问题,而有人可能会告诉你如何去做。 – 2014-09-01 08:15:19

+0

这对我不起作用: '不能调用'undefined'的方法'...' mongo version 2.6.6 – 2015-02-06 19:29:09