mongoose按位置/索引更新数组中的项目

时间:2016-12-12 08:56:32

标签: node.js mongodb mongoose

有没有办法更新例如mongoose数组中的第二项?

架构:

title: String,
answer: [{
    content: String,
    votes: Number
}]

在我的情况下,我想更新第一个或第二个答案,因此它还有1票。

3 个答案:

答案 0 :(得分:3)

我不是一个猫鼬专家。但似乎有一些answer你可以参考 所以简短的回答是肯定的,你可以通过指定索引来更新数组元素。在shell中它将是:

//+------------------------------------------------------------------+
//|                                  __StackOverflow_CryptENCODE.mq4 |
//|                                               msMODs (1987-2016) |
//|                                                       nowhere.no |
//+------------------------------------------------------------------+
#property copyright "msMODs (1987-2016)"
#property link      "nowhere.no"
#property version   "1.00"
#property strict
#property script_show_inputs
extern string  aKnown_OriginalSTRING_asMql4STRING     = "How to decrypt an MT4 / AES256 encrypted string with PHP tools?";
       uchar   aKnown_OriginalSTRING_ucharCONTAINER[];
extern string  aKnown_SecretKEY_asMql4STRING          = "123456789o123456789o12";
       uchar   aKnown_SecretKEY_ucharCONTAINER[32];
       uchar   aCryptoBLOB_ucharCONTAINER[];
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void   OnStart(){
       StringToCharArray( aKnown_OriginalSTRING_asMql4STRING,
                          aKnown_OriginalSTRING_ucharCONTAINER,
                          0,
                          StringLen( aKnown_OriginalSTRING_asMql4STRING )
                          );
       StringToCharArray( aKnown_SecretKEY_asMql4STRING,
                          aKnown_SecretKEY_ucharCONTAINER,
                          0,
                          32
                          );

       int        aFH = FileOpen( "DEMO_OUTPUT.txt", FILE_WRITE | FILE_TXT );
       FileWrite( aFH, "START: GetLastError() == ", GetLastError(), "\n" );
       FileFlush( aFH );

       ResetLastError();

       int nBYTEs = CryptEncode( CRYPT_AES256,                        // a principally unsure ENUM_ ( ref. above )
                                 aKnown_OriginalSTRING_ucharCONTAINER,
                                      aKnown_SecretKEY_ucharCONTAINER,
                                           aCryptoBLOB_ucharCONTAINER
                                 );

       if (  nBYTEs > 0 ){
             FileWrite( aFH, StringFormat( "OK.\nMQL4 CryptEncode() has produced [nBYTEs == %d ] bytes.\nMQL4 aCryptoBLOB_asHEX\n== [%s]",
                                            nBYTEs,
                                            show_asHEX( aCryptoBLOB_ucharCONTAINER )
                                            )
                        );
             Comment( "INF:",StringFormat( "OK.\nMQL4 CryptEncode() has produced [nBYTEs == %d ] bytes.\nMQL4 aCryptoBLOB_asHEX\n== [%s]\n\nSTORED IN GlobalVariable()...",
                                            nBYTEs,
                                            show_asHEX( aCryptoBLOB_ucharCONTAINER )
                                            )
                        );
       }                           
       else
             FileWrite( aFH, StringFormat( "ERR: in MQL4 CryptEncode()[ Err == %d ].",
                                            GetLastError()
                                            )
                        );
      FileFlush( aFH );
      FileClose( aFH );               
   }
//+------------------------------------------------------------------+
string show_asHEX( uchar &_ucharCONTAINER_arr[], int count = -1 ){
       string HEX_asPrintableSTRING = "";
       if (  count <  0
          || count >  ArraySize( _ucharCONTAINER_arr )
          )  count =  ArraySize( _ucharCONTAINER_arr );
       for (  int ii = 0; ii <  count; ii++ )
               HEX_asPrintableSTRING += StringFormat( "%.2X", _ucharCONTAINER_arr[ii] );
       return( HEX_asPrintableSTRING );
   }
//+------------------------------------------------------------------+

其中START: GetLastError() == 0 OK. MQL4 CryptEncode() has produced [nBYTEs == 64 ] bytes. MQL4 aCryptoBLOB_asHEX == [1979FE46DB64652067C136F57F0971F20FB5C407CE043AAF972C8AED3DEB6D4260181448FE2FDF69AEA7DD8B33B1484A21935AAFBB649FB95DBB05BBA88E4A31] 是您要更新的元素的索引。我确定你能找到相应的语法如何用mongoose写这个。

在我看来,通过索引更新数组并不是一个好主意。如果元素被移除/插入怎么办?嵌入式数组元素就像db.collection.update({...}, {$inc: {"answer.0.votes": 1}}) 中的一对多关系。他们应该更容易找到像0这样的唯一标识符。建议的数据结构:

RDBMS

ObjectId查询以查找您正在投票的确切答案:

{
    title: "This is a question",
    answer: [{
        id: ObjectId("584e6c496c9b4252733ea6fb"),
        content: "Answer",
        votes: 0
    }]
}

其中id表示数组中匹配的元素。

编辑 - 2018-04-03

  1. 如果只有一个条件,则不需要db.collection.update({"answer": {$elemMatch: {id: ObjectId("584e6c496c9b4252733ea6fb")}}}, {$inc: {"answer.$.votes": 1}}); 。它意味着在一个元素中匹配2个或更多个条件。如果没有$,则不同的条件可能匹配数组中的不同元素。在大多数情况下都不会出现这种情况。
  2. 从3.6开始,MongoDB引入了$[],它允许您在一个$elemMatch中更新数组中的所有元素。

答案 1 :(得分:1)

试试这个:

Model.findOne({ title: 'your-title' }, function (err, doc){
  doc.answer.0.votes.$inc(); // increases votes on first answer by 1
  doc.save();
});

答案 2 :(得分:1)

尝试一下。我希望这会起作用

Model.findOneAndUpdate({query},{["answer.${element index}.content:new_data"]},{new:true},(err,docs)=>{})