2015-04-14 295 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都是相同的長度。 –

相關問題