2014-09-23 50 views
1

我是新來的節點(v0.10)堆棧。 我想實現以下目標:需要關於node.js多語言演示的指導

我已(希望)在最新的MongoDB等多語種的文章:

_id 
...more fields... 
text: [ 
{lang: 'en', title: 'some title', body: 'body', slug: 'slug'}, 
.... 
] 

每次我顯示特定語言的文章中,我查詢,如下所示:

var query = Model.findOne({'text.slug': slug}); 
query.exec(function(err, doc){ 
async.each(doc.text, function(item, callback){ 
    if (item.lang == articleLang) { 
     //populate the article to display 
    } 
}); 

res.render('view', {post:articleToDisplay}); 
}); 

Slug對每種語言都是獨一無二的! 我遇到的問題是,mongo將返回整個文檔與所有的subdocs,而不僅僅是我搜索的subdoc。現在我必須選擇遍歷所有的子目錄,並在客戶端顯示相應的子目錄,或者在服務器上使用async.each來獲取我需要的子目錄,並只發送給其中的一個。我正在做與服務器上的異步。這可以嗎?同樣,異步異步迭代,但節點仍然等待整個循環完成,然後呈現視圖。我錯過了什麼,認爲用戶實際上被阻止,直到async.each完成?我仍然試圖圍繞這個異步執行包圍我的頭。有沒有一種方法可以改進我如何管理這些代碼?這似乎是與subdocs相當標準的程序!

在此先感謝您的幫助。

回答

0

要達到您想要的效果,您需要使用aggregation pipeline。使用簡單的findOne()不會有幫助, ,因爲您必須修改代碼中的子文檔,而不是允許mongodb執行此操作。 find()findOne()返回文檔 文件與搜索條件匹配時的整個文檔。

在聚合pipleline中,您可以使用$unwind$match運算符來實現此目的。

$unwind: 

解構陣列場從輸入文檔輸出爲每個元件的 文檔。每個輸出文檔都是輸入文檔 ,數組字段的值由元素替換。

首先根據text值數組展開文檔。

$match: 

過濾的文件只傳遞符合 指定條件(S)到下一個流水線級的文件。

然後使用$match運算符來匹配相應的文檔。

db.Model.aggregate([ 
{$unwind:"$text"}, 
{$match:{"text.slug":slug,"text.lang":articleLang}} 
]) 

這樣做將返回你只含有一個對象的text場只有一個文檔。如:(注意,在輸出的text字段不是數組)

{ "_id" : ... ,.., "text" : { "slug" : "slug", "lang" : "en" ,...} } 
+0

謝謝!如果你可以回答我的問題是否異步。每個人都在阻止應用程序,直到所有選項都被迭代,並構成接受這個答案。 – sunlover 2014-09-24 12:21:23

+0

是的,它仍然意味着您正在異步而不是按順序遍歷所有數組項目。 http://www.sebastianseilund.com/nodejs-async-in-practice - 更好地理解異步的工作原理。 async.each()..仍然是異步執行的。但是,只有當所有任務完成時,即所有單獨的文本字段都被迭代,並且即將渲染視圖時,纔會重新獲得控制權。相反,您可以設置一些變量來確定您的匹配已找到,然後通過停止所有其他任務調用最終回調或退出。 – BatScream 2014-09-24 13:24:35

+0

@sunlover:標籤爲上述響應。 – BatScream 2014-09-24 13:31:21