2015-11-22 34 views
1

我想返回流星中的光標(使用MongoDB)。如何在Mongo(流星)中查找找到數組匹配的文檔的查找?

我希望找到的文件(MessageThreads集合),參與者的字段的數組我通過在完全匹配。

下面是一個示例MessageThread文件

{ 
    "_id": "YYSELCguhLurTeyNY", 
    "creator": "RLmnidY6GypdqDXZu", 
    "participants": [ 
    "SNhRq4vQpwFBjnTSH", 
    "RLmnidY6GypdqDXZu" 
    ], 
} 

當我執行方法addMessage方法,我試圖首先檢查線程是否存在,其中participants與我傳入的數組完全匹配。此數組將從新消息格式to字段中制定。

所以,如果我所有的participants陣列都在文檔participants字段內但沒有其他字段,則只應返回文檔。例如:如果文件中不存在第三人,但該文件不屬於新消息to字段,則不應退回該文件。

目前,這是我的查詢,這顯然是過於簡單化。

existingThread = MessageThreads.findOne(participants: participants) 

任何指針?謝謝

編輯:我使用的是提供的重複答案有一個問題(但尚未獲準對其他線程評論)如果數組是不同

出於某種原因existingThread仍然找到一個文檔,但size是正確的。

編輯2:

下面是我在整個事件的方法,它可以幫助破譯我要去的地方錯誤的代碼。在coffeescript(請原諒,不能在它工作,對不起)。

Meteor.methods 

newMessage: (recipientIds, messageContent) -> 

if !Meteor.userId() 
    return false 

userId = Meteor.userId() 

check recipientIds, [String] 
check messageContent, String 

participants = recipientIds 
participants.push(userId) 
participantCount = _.size(participants) 

existingThread = MessageThreads.findOne participants: 
    $size: participantCount 
    $in: participants 

if existingThread? 
    console.log "Thread exists: #{existingThread._id}" 

    MessageThreads.update existingThread, 
    $addToSet: messages: {sender: userId, content: messageContent} 
    $set: lastUpdated: new Date() 


else 
    newThreadId = MessageThreads.insert 
    creator: userId 
    participants: participants 
    messages: [ 
     { 
     sender: userId 
     content: messageContent 
     createdAt: new Date() 
     } 
    ] 
    lastUpdated: new Date() 

    return newThreadId 
+0

開始用谷歌搜索'mongodb的陣列確切match'。這揭示了很多有用的答案。 –

+2

非常感謝,你是對的我顯然不是非常有效地搜索!這個SO問題似乎有一個這樣的答案。 http://stackoverflow.com/questions/29774032/mongodb-find-exact-array-match-but-order-doesnt-matter –

+0

:P好的發現,忘記了答案可以適用於你的情況很好。 – chridam

回答

0

您需要在您的查詢的$all運營商,其選擇的文件,其中一個字段的值是包含所有指定元素的數組。當你想返回一個遊標時,由於它返回一個遊標,所以方法更合適。它不會立即訪問數據庫或返回文檔。要訪問光標中的文檔,光標提供fetch()以返回所有匹配文檔map()forEach(),以遍歷所有匹配文檔observe()observeChanges(),以在匹配文檔集更改時註冊回調。

對於你的情況,示例實現會是這個樣子:

var existingThreadsCursor = MessageThreads.find({ "participants": { "$all": participants} }); 
var count = 0; 
existingThreadsCursor.forEach(function (thread){ 
    console.log("Thread with participants: " + JSON.stringify(thread.participants)); 
    count++; 
}); 
+0

非常感謝!當我說我想返回一個遊標時,我認爲我誤導了,我認爲'findOne'沒問題,因爲我真的想知道這個線程是否存在。如果我只想要完全匹配,那麼$ all是否仍然有效?我認爲它工作,如果它發現我陣列中的所有項目,但仍然可以工作,如果其他項目也在其中? –

+0

是的,它仍然可以工作,因爲它與字段包含指定數組元素的文檔相匹配。所以'findOne'與'$ all'一起會返回一個文檔,如果它有一個精確的數組匹配,否則返回null。 – chridam

+0

謝謝我認爲我遇到了$ all的問題,如果數組的順序不同,它不匹配。 –