2017-03-08 7 views
2

私はこのRAMDA>マングース>データ構造操作

var TermSchema = new Schema({ 
group: {type:String}, 
key: {type:String}, 
translations:[{ 
    clientId:{type:Number,default:config.gdgId}, 
    lang:{type:String}, 
    val:{type:String}, 
    needsTrans:{type:Boolean,default:false} 
}], 
updatedAt:{type:Date, default: Date.now}, 
updatedBy:{type:String, default: ''}, 
createdBy:{type:String, default: ''}, 
createdAt:{type:String, default: Date.now}, 
comments:{type:String, default: ''}, 
softDelete:{type:Boolean,default: false} 

}のように見えるモデルを持っています)。

しかし、特定のクライアントの翻訳のインスタンスをlang> group> key>変換のi18n形式に変換する必要があります。私の元のコードは、私が知っているこの

function companyTerms(clientId){ 
var deferred = q.defer(); 
var companyObj = {'en-US':{},'de-DE':{},'en-GB':{},'es-SP':{},'fr-FR':{},'it-IT':{},'nl-NL':{},'pt-BR':{},'zh-CN':{}}; 
Term.find({'translations':{$elemMatch:{'clientId':clientId}}, 'softDelete': false}, function(err,terms){ 
    _.each(terms,function(term){ 
     _.each(term.translations,function(trans){ 
     if(companyObj[trans.lang]){ 
      companyObj[trans.lang][term.group] = {}; 
     } 
     }) 
    }) 
    _.each(terms,function(term){ 
     _.each(term.translations,function(trans){ 
     if (trans.clientId == clientId && companyObj[trans.lang]) { 
      companyObj[trans.lang][term.group][term.key] = trans.val; 
     } 
     }) 
    }) 
    deferred.resolve(companyObj); 
    }) 
    return deferred.promise; 
    }  

グロスのように見えました!

私はこのコードをクリーンアップし、応答をスピードアップする方法を探していました。私の最初の試みは、Ramdaライブラリをヘルパー関数で使用することでした。

function addToLang(groupObject){ 
let mapValues = obj => { 
    obj['group'] = groupObject['group'] 
    obj['key'] = groupObject['key'] 
    return obj 
    } 
    return R.map(mapValues, groupObject.translations) 

}

function companyTerms(clientId){ 
return Term.find({'translations':{$elemMatch:{'clientId':clientId}}, 'softDelete': false}) 
    .then(R.map(R.pick(['group','translations','key']))) 
    .then(R.map(addToLang))//Adds group field to each translation object 
    .then(R.flatten())//Flattens the different key objects 
    .then(R.filter(R.propEq('clientId',parseInt(clientId))))//Filters out non-client translations 
    .then(R.groupBy(R.prop('lang')))//Groups by language 
    .then(R.map(R.groupBy(R.prop('group'))))//Sub-groups by group 
    .then(R.map(R.map(R.groupBy(R.prop('key')))))//Has key as final group-value 
    .then(R.map(R.map(R.map(R.pick(['key'])))))//Removes all other meta-data 
} 

しかし、私はヘルパー関数に悩まさとちょうど「集約」コンストラクタにジャンプして、私の最終的なコードはこのように見えたことを決定しました。

function companyTerms(clientId){ 
return Term.aggregate([ 
    { 
    "$unwind":"$translations" 
    },{ 
    "$match":{ 
     "translations.clientId":parseInt(clientId), 
     "softDelete":false 
    } 
    },{ 
    "$project":{ 
     key:"$key", 
     group:"$group", 
     lang:'$translations.lang', 
    } 
    }]) 
    .then(R.groupBy(R.prop('lang')))//Groups by language 
    .then(R.map(R.groupBy(R.prop('group'))))//Sub-groups by group 
    .then(R.map(R.map(R.groupBy(R.prop('key')))))//Has key as final group-value 
    .then(R.map(R.map(R.map(R.pick(['key'])))))//Removes all other meta-data 
}; 

これは、はるかに簡潔以前よりませんでしたが、それは以前よりもはるかに高速です。

+2

ここに質問がありますか? –

+0

私の一般的なアイデアは、この機能をより簡潔にするためのアイデアを募集することでした。 –

+0

あなたはおそらくその質問をより明確にするべきです。あなたはそれを編集して説明を追加することができます。 –

答えて

2

2つの可能性:

  • あなたはそのヘルパー心配している場合は、これがでテストするために、任意のデータなしで1の視点から(に見える、コードの残りの部分と合わないので、 )ポイントフリーの代替のように:

    R.lift(R.map)(R.compose(R.merge, R.pick(['group', 'key'])), R.prop('translations')) 
    
  • あなたはおそらく、これらすべてのthen秒を必要としません。最初の呼び出しの後に非同期のものがないように見えます。 thenを一緒にチェーンするほうが便利ですが、リストが長くなるにつれて光沢が失われ始めます。

    単純にpipeの機能を一緒に呼び出して、1つのthenの中で組み合わせを呼び出すことができます。 、

    someAsyncFn() 
        .then(f1) 
        .then(f2) 
        .then(f3) 
        .then(f4) 
    

    someAsyncFn().then(pipe(f1, f2, f3, f4)) 
    

これらのいずれもが、驚天動地のです:ポイントは限りfnがすべて同期している...、f2f1として、これらは等価であるということですいずれかのコードをクリーンアップするのに役立つかもしれません。

+0

ありがとうScott、私はそれを行こう! –