изменение типа mongodb на массив - PullRequest
17 голосов
/ 13 сентября 2011

У меня есть поле в mongodb, это строка.{"field": "some text"}, я хочу преобразовать их все в массивы.{"field": ["some text"]}

Я знаю, что могу просто просмотреть все документы, получить поле, затем обновить, но мне интересно, есть ли более чистый способ.

Ответы [ 6 ]

10 голосов
/ 24 сентября 2012

Ответ Нитина Гарга выше почти работает, за исключением того, что его пример преобразует строку в хеш, а НЕ строку в массив.

Принимая во внимание комментарии Джоэла Харриса, правильное решение будет выглядеть следующим образом:

db.jobs.find( { "jobLocationCity" : { $type : 2 } } ).snapshot().forEach( function (x) {
    x.jobLocationCity = [ jobLocationCity ];
    db.jobs.save(x);
});

Или при использовании db.eval:

function f() {
    db.jobs.find( { "jobLocationCity" : { $type : 2 } } ).snapshot().forEach( function (x) {
        x.jobLocationCity = [ jobLocationCity ];
        db.jobs.save(x);
    });
}
db.eval(f);
5 голосов
/ 14 января 2013

На самом деле поиск ({"jobLocationCity": {$ type: 2}}) не будет работать должным образом, потому что если вы в следующий раз запустите скрипт обновления, он снова будет обрабатывать элементы ['mystring'] как строковый тип.

Вы должны использовать что-то подобное, чтобы предотвратить это:

db.message_info.find( { "jobLocationCity" : { $type : 2 } }  ).snapshot().forEach(
  function (x) {
    if (!Array.isArray(x.jobLocationCity)){
        x.jobLocationCity = [ x.jobLocationCity  ];
        db.jobs.save(x);
    }
  }
)

см. http://docs.mongodb.org/manual/reference/operators/

3 голосов
/ 24 января 2012

вместо этого попробуйте

Чтобы изменить тип поля со строки на массив в mongoDB

db.jobs.find( { "jobLocationCity" : { $type : 2 } } ).forEach( function (x) {
    x.jobLocationCity = {"Location":x.jobLocationCity};
    db.jobs.save(x);
});

см. Ссылку возможных значений $ type

3 голосов
/ 13 сентября 2011

Вы можете сделать это с помощью функции «Уменьшить» карты / уменьшить, чтобы сохранить всю обработку в mongodb.По сути, вы должны использовать map / reduction, чтобы поместить результаты в новую коллекцию, а затем скопировать их обратно в старую коллекцию (или удалить старую и переименовать новую).Преимущество этого в том, чтобы хранить все внутри монго.

Обновление : другой вариант может быть для вас - использовать db.eval .db.eval выполняется на сервере, поэтому обновления будут выполняться на сервере без трафика / задержки.

Я думаю, что единственный другой вариант, как вы описали, - сделать это на клиенте, запрашивая и обновляя каждый.

1 голос
/ 13 июня 2019

Начиная с Mongo 4.2, db.collection.update() можно принять конвейер агрегации, наконец, разрешив обновление поля на основе его текущего значения:

// { field: "some text" }
db.collection.update(
  {},
  [{ $set: { field: { ["$field"] } } }],
  { multi: true }
)
// { field: [ "some text" ] }
  • Первая часть {} - это запрос на совпадение, отфильтровывающий, какие документы нужно обновить (в данном случае все документы).

  • Вторая часть [{ $set: { field: { ["$field"] } } }] - это конвейер агрегации обновлений (примечаниеквадратные скобки, обозначающие использование агрегационного конвейера).$set (псевдоним $addFields) - это новый оператор агрегирования, который в этом случае заменяет значение поля (просто заключая его в массив).Обратите внимание, как field изменяется непосредственно на основе его собственного значения ($field).

  • Не забудьте { multi: true }, иначе будет обновлен только первый соответствующий документ.

0 голосов
/ 14 сентября 2011

но мне интересно, есть ли более чистый способ ..

Краткий ответ - нет.

MongoDB не имеет ни одной операции или команды для выполненияa «тип изменения».

Самый быстрый способ сделать это, вероятно, использовать один из драйверов и внести изменения.Вы можете использовать оболочку и написать цикл for, но с точки зрения необработанной скорости другие драйверы могут быть быстрее.

При этом самая медленная часть процесса будет загружать все данные издиск в память, которая будет изменена, а затем сбросить эти данные обратно на диск.Это было бы верно даже с волшебной командой «изменить тип».

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