2017-09-18 28 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操作。

一个请求。

相关问题