MongoDB - Обновление типа поля всех объектов в массиве с String на Int32 / 64 - PullRequest
1 голос
/ 29 марта 2020

Я довольно новичок в mongodb, поэтому, пожалуйста, потерпите меня.

Что касается заголовка, то я хочу добиться того, чтобы преобразовать указанное поле c во все документы в массиве документа из String to Int, как мне это сделать?

Sample Do c:

{
 reviews:[
    {
      snid:"1242"
    },
    {
      snid:"8392"
    }
 ]
}

И моя цель - преобразовать все snid с String до Int32

, насколько я понимаю, мы можем использовать что-то вроде db.collection.update(), но это обновит поле c, не массив.

Еще одна попытка

db.collection.find({},{reviews:1,_id:0},(err,doc)=>{
    //How do i push it back to the document
})

Но, как вы можете сказать, я не совсем уверен, как мы должны * sh обновлять документ обратно в тот же массив

Любые идеи будут с благодарностью!

1 Ответ

0 голосов
/ 30 марта 2020

1) Если вы используете версию MongoDB> = 4.2, попробуйте следующий запрос:

db.collection.update({'reviews.snid' : {$exists : true}}, [
  {
    $set: {
      reviews: {
        $map: { input: "$reviews", in: { 'snid': { $toInt: "$$this.snid" } } }
      }
    }
  }
],{multi :true})

Вышеупомянутый запрос использует Агрегирующий конвейер в .update(), который был представлен в версии 4.2, Вы также можете использовать .updateMany() вместо .update().

Работает с документами следующего типа:

/* 1 */
{
    "_id" : ObjectId("5e810f5ec16b5679b43a2f0e"),
    "reviews" : [ 
        {
            "snid" : '1242'
        }, 
        {
            "snid" : '8392'
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("5e810f6ac16b5679b43a310c"),
    "reviews" : [ 
        {
            "snid" : '1242232'
        }, 
        {
            "snid" : '8391232'
        }
    ]
}

/* 3 */
{
    "_id" : ObjectId("5e8110b1c16b5679b43a5148"),
    "abc" : 1
}

/* 4 */
{
    "_id" : ObjectId("5e8110c3c16b5679b43a52f9"),
    "reviews" : []
}

/* 5 */
{
    "_id" : ObjectId("5e811359c16b5679b43a9229"),
    "reviews" : [ 
        {
            "abc" : "1"
        }
    ]
}

Но приведенный выше запрос на обновление будет частично работать, если вы делаете c, как показано ниже:

{
    "_id" : ObjectId("5e811359c16b5679b43a9230"),
    "reviews" : [ 
        {
            "abc" : "1"
        },
        {
            "snid" : "123"
        }
    ]
}

В этом случае вам нужно использовать $ cond , чтобы сделать условная проверка в $map, чтобы увидеть, есть ли у текущего объекта ключ snid , затем преобразовать значение или передать тот же объект, что и в массив 'reviews'.

2) На всякий случай, если ваша версия MongoDB <<code>4.2 / 4.0 &> 3.2 - Вы можете использовать .bulkWrite () :

Причина, по которой вы не можете использовать Агрегационный конвейер в обновлении и также $ toInt . Поэтому вам нужно сделать .find(), чтобы получить целые документы и написать код, чтобы преобразовать их из строк в целые числа, и использовать .bulkWrite(), чтобы обновить документы за один вызов обновления БД (вы можете взять _id в качестве ключа для каждого документа).

3) Вы также можете написать запрос агрегации для существующей коллекции и использовать $ out для обновления всей коллекции или записи результата агрегации в новую коллекцию, выполнив всего один запрос. Я бы предпочел временно записать его в новую коллекцию, чтобы проверить правильность данных и переименовать новую коллекцию в существующую, назвав существующую чем-то, заканчивающимся _backup, используемым в качестве резервной копии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...