2017-09-18 29 views
0

我正在構建一個同義詞庫應用程序,對於此問題,關鍵注意事項是我要爲特定內容添加同義詞列表(具有相同含義的單詞)字(例如 - 「貓科動物」,「雄貓」,「貓」是「貓」的同義詞)將「編程」數組推送到一個對象的數組屬性

我有一個Word對象,有一個屬性 - 「同義詞」 - 這是一個數組。 我將爲Word同義詞屬性添加同義詞數組。 據MongoDB的文檔see here,到數組的所有索引追加到文檔的數組屬性一次的唯一方法是嘗試以下操作:

db.students.update(
    { _id: 5 }, 
    { 
    $push: { 
     quizzes: { 
      $each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ], 
     } 
    } 
    } 
) 

讓我們重新編寫的解決方案,以適應我的數據,我們進一步冒險之前。

db.words.update(
     { baseWord: 'cat' }, 
     { 
     $push: { 
      synonyms: { 
       $each: [ { _id: 'someValue', synonym: 'feline' }, { _id: 'someValue', synonym: 'puss' }, { _id: 'someValue', synonym: 'tomcat' } ], 
      } 
     } 
     } 
    ) 

尼斯和簡潔,但不是我想要做的。

如果您事先不知道您的數據並且想要添加一個動態數組,那該怎麼辦? 我目前的解決方案是分裂陣列並運行一個foreach()循環,導致陣列被附加到Word對象的同義詞數組屬性,像這樣:

//req.body.synonym = 'feline,tomcat,puss'; 
var individualSynonyms = req.body.synonym.split(','); 

individualSynonyms.forEach(function(synonym) { 

      db.words.update(        
       { "_id": 5 },      
       { $push: //this is the Word.synonyms 
        { synonyms: 
         { 
         $each:[{ //pushing each synonym as a Synonym object      
           uuid : uuid.v4(),          
           synonym:synonym,          
          }]         
         } 
        } 
       },{ upsert : true }, 
       function(err, result) { 
        if (err){ 
         res.json({ success:false, message:'Error adding base word and synonym, try again or come back later.' }); 
         console.log("Error updating word and synonym document"); 
        } 
        //using an 'else' clause here will flag a "multiple header" error due to multiple json messages being returned 
        //because of the forEach loop 
        /* 
        else{        
         res.json({ success:true, message:'Word and synonyms added!' }); 
         console.log("Update of Word document successful, check document list"); 
        } 
        */    
       }); 
       //if each insert happen, we reach here 
       if (!err){ 
        res.json({ success:true, message:'Word and synonyms added!.' }); 
        console.log("Update of Word document successful, check document list"); 
       }  
     }); 
}   
  • 這按預期工作,但你可能會在底部註明和發佈,其中有一條註釋掉的ELSE子句,並檢查'​​if(!err)'。 如果ELSE子句被執行,我們會得到一個「多頭」錯誤,因爲循環會爲單個請求產生多個JSON結果。

除此之外,'if(!err)'會拋出一個錯誤,因爲它沒有範圍到從.update()函數回調中的'err'參數。 - 如果有一種方法避免使用forEach循環,並直接將同義詞數組提供給一個update()調用,那麼我可以在回調中使用if(!err)。

您可能會想:「只要刪除'if(!err)'子句」,但似乎不清楚發送JSON響應事先沒有進行某種最終錯誤檢查,是否if,else,else if

我無法在文檔或本網站上找到此特定方法,對我而言,如果可以完成,似乎是最佳做法,因爲它允許您在發送響應之前執行最終錯誤檢查。 我很好奇這是否可以實際完成。

我沒有使用控制檯,但在調用每個對象以方便閱讀之前,我包含了一個名稱空間前綴。

+0

有一件事答案沒有解決,我想知道如果可能的話。不管它是非常有用的,我都會接受答案。 在我發佈的問題中,發佈到同義詞數組的每個同義詞都會收到一個uuid屬性及其同義詞屬性(表示我們將添加到'Word'對象中的那個單詞)。 在您的解決方案中,正在添加的這些同義詞不再具有uuid。在你發佈最後一篇文章之後,我意識到不需要我向這些嵌套屬性發布uuids,但是我很好奇它是否可以完成。 – OisinFoley

+0

夥計。我向你展示了添加uuid。我基本上都在做你的代碼,除非是正確的。如果你有問題,那就出面問問他們。不要靜靜地坐着幾天。 –

+0

Word條目的示例輸出爲: {「_id」:ObjectId(「59c2fae359bf1ed0fb70d83e」),「uuid」:「someValue」,「baseWord」:「aaa」,「同義詞」:[{「synonym」:「 「_id」:ObjectId(「59c2fae359bf1ed0fb70d83e」),「bbb」},{「synonym」:「ccc」},{「synonym」:「ddd」}],「__v」:0} 而不是說 {「_id」 「uuid」:「someValue」,「baseWord」:「aaa」,「同義詞」:[{uuid:「someValue」,「synonym」:「bbb」},{uuid:「someValue」,「synonym」:「ccc 「},{uuid:」someValue「,」synonym「:」ddd「}],」__v「:0} 只是試圖在好奇和害蟲Neil之間找到正確的折衷。 – OisinFoley

回答

1

由於$each以「數組」作爲參數,因此不需要「迭代」。簡單地.map().split()所產生的陣列具有附加數據:

db.words.update(        
    { "_id": 5 },      
    { $push: { 
    synonyms: { 
     $each: req.body.synonym.split(',').map(synonym => 
     ({ uuid: uuid.v4, synonym }) 
    ) 
    } 
    }}, 
    { upsert : true }, 
    function(err,result) { 
    if (!err){ 
     res.json({ success:true, message:'Word and synonyms added!.' }); 
     console.log("Update of Word document successful, check document list"); 
    }  
    } 
); 

所以.split()產生從字符串,你「改造」使用.map()uuid值的陣列的「陣列」和"synonym"從元件.split()。這是一個直接的「陣列」,與$each一起應用到$push操作。

一個請求。

相關問題