2015-04-14 311 views
2

我有一个集合,其中_id的形式为[message_code]-[language_code],另一个集合的_id只是[message_code]。我想要做的是从第一个集合中查找_id的message_code部分未出现在第二个集合中的所有文档。如何检查一个集合中某个_id的一部分是否出现在另一个集合中

例子:

> db.colA.find({}) 
{ "_id" : "TRM1-EN" } 
{ "_id" : "TRM1-ES" } 
{ "_id" : "TRM2-EN" } 
{ "_id" : "TRM2-ES" } 
> db.colB.find({}) 
{ "_id" : "TRM1" } 

我想要一个查询,从可乐返回TRM2-EN和TRM-ES。当然,在我的实时数据中,每个集合中都有数千条记录。

根据this question正在尝试做类似的事情,我们必须保存来自对colB的查询的结果,并在针对colA的查询中使用$ in条件。在我的情况下,我需要去掉-[language_code]部分,然后再进行比较,但是我找不到这样做的方法。

如果一切都失败了,我就创建可乐只包含消息代码一个新的领域,但有没有更好的办法做到这一点?

编辑: 基于迈克尔的回答,我能想出这个解决方案:

var arr = db.colB.distinct("_id") 
var regexs = arr.map(function(elm){ 
    return new RegExp(elm); 
}) 
var result = db.colA.find({_id : {$nin : regexs}}, {_id : true}) 

编辑: 经仔细检查,上面的方法不起作用毕竟。最后,我只需要添加新的字段。

+0

什么不起作用正则表达式阵列?为我工作得很好。如果需要,我可以添加演示。 – styvane

+0

您的方法适用于我发布的示例,但我的实时数据有太多的消息代码,其中一些消息代码恰好是其他字符的子字符串,导致选择的记录太多。当然,仅仅通过查看我的原始问题是无法知道这一点的,所以我会让你的答案被接受并且得到满足。 –

+0

好吧,也许你应该向样本文档另外一个问题,如果你仍然有问题 – styvane

回答

2

免责声明:这是一个小黑客,它可能不会很好。

var arr = db.colB.distinct('_id'); 
arr.map(function(elm, inx, tab) { 
    tab[inx] = new RegExp(elm); 
}); 

db.colA.find({ '_id': { '$nin': arr }}) 
+2

我无法让你的代码按原样工作,但我确实得到了一个可以工作的查询。我会用它更新我的问题。感谢您指点我正确的方向! –

1

我一个新的字段添加到colA因为你可以索引它,如果你在每个collection分裂成千上万的documents弦将是非常慢的。

但是,如果您不想这样做,您可以利用汇总框架的$substr运算符来提取[message-code],然后对结果执行$match

+0

我不知道该聚合框架的,所以感谢指出了这一点给我。不幸的是,$ substr不适合我,因为它需要开始和长度索引,并不是所有的我的ID都是相同的长度。 –

相关问题