推送"程序化"数组到Object的数组属性

时间:2017-09-18 20:56:56

标签: javascript arrays mongodb nosql

我正在构建一个同义词库应用程序,对于这个问题,关键注意事项是我为特定单词添加了一个同义词列表(具有相同含义的单词)(例如 - &# 34;猫科动物"," tomcat"," puss"是" cat")的同义词

我有一个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()函数回调中的参数。 - 如果有办法避免使用forEach循环,并直接将同义词数组提供给单个update()调用,那么我可以在回调中使用if(!err)。

您可能会想:"只需删除' if(!err)'条款",但是如果没有事先进行某种最终错误检查就发送JSON响应似乎是不洁净的,无论是if,else,else if等等。

我在文档或本网站上找不到这种特殊的方法,对我来说,如果可以做到这似乎是最好的做法,因为它允许您在发送响应之前执行最终的错误检查。 我很好奇这是否可以实现。

我没有使用控制台,但我在调用每个对象之前都包含了一个名称空间前缀,以便于阅读。

1 个答案:

答案 0 :(得分: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操作。

一个请求。