Я хочу добавить данные в массив к моей существующей схеме в MongoDB, используя Node js [duplicate]

Здесь доступны различные доступные варианты, а также плюсы и минусы каждого из них здесь .

Предлагаемые варианты:

  • Подготовьте SELECT my_column FROM my_table WHERE search_column = ?, выполните его для каждого значения, а UNION - на стороне клиента. Требуется только одно подготовленное заявление. Медленный и болезненный.
  • Подготовьте SELECT my_column FROM my_table WHERE search_column IN (?,?,?) и выполните его. Требуется один подготовленный оператор в размере IN-списка. Быстро и очевидно.
  • Подготовьте SELECT my_column FROM my_table WHERE search_column = ? ; SELECT my_column FROM my_table WHERE search_column = ? ; ... и выполните его. [Или используйте UNION ALL вместо этих точек с запятой. --ed] Требуется один подготовленный оператор в размере IN-списка. Глубоко медленно, строго хуже, чем WHERE search_column IN (?,?,?), поэтому я не знаю, почему блоггер даже предложил его.
  • Используйте хранимую процедуру для построения набора результатов.
  • Подготовьте N разных запрос размера списка IN-list; скажем, с 2, 10 и 50 значениями. Чтобы выполнить поиск IN-list с 6 различными значениями, введите запрос размера-10, чтобы он выглядел как SELECT my_column FROM my_table WHERE search_column IN (1,2,3,4,5,6,6,6,6,6). Любой достойный сервер будет оптимизировать повторяющиеся значения перед запуском запроса.

Однако ни один из этих параметров не супер.

В этих местах ответили на дублирующие вопросы с одинаково разумными альтернативами, все еще ни один из них не супер:

Правильный ответ, если вы используете JDBC4 и сервер, который поддерживает x = ANY(y), должен использовать PreparedStatement.setArray, как описано здесь :

Кажется, что нет способа заставить setArray работать с IN-lists.

66
задан Neurax 10 October 2015 в 06:41
поделиться

4 ответа

Предполагая, var friend = { firstName: 'Harry', lastName: 'Potter' };

Есть два варианта:

Обновление модели в памяти и сохранение (простой javascript array.push):

person.friends.push(friend);
person.save(done);

или

PersonModel.update(
    { _id: person._id }, 
    { $push: { friends: friend } },
    done
);

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

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

95
ответ дан reddisht 15 August 2018 в 16:33
поделиться
  • 1
    Я думал, что второй вариант был на самом деле более безопасным с точки зрения одновременной защиты от записи? Вы случайно сказали последнее, когда хотели сказать, что кто-то бывший? – Will Brickner 15 November 2017 в 06:46
  • 2
    Да, я только что проверил и (в ноябре 2017 года), безопасно использовать функцию mongoose update, в то время как НЕВОЗМОЖНО , чтобы найти документ, изменить его в памяти, а затем вызовите метод .save() в документе. Когда я говорю, что операция «безопасна», это означает, что даже если один, два или 50 изменений применяются к документу, все они будут успешно применены, а поведение обновлений будет таким, как вы ожидаете. По сути, манипуляция с памятью небезопасна, потому что вы можете работать с устаревшим документом, поэтому при сохранении изменения, которые произошли после того, как шаг выборки потерян. – Will Brickner 15 November 2017 в 06:55
  • 3
    @Will Brickner - общий рабочий процесс, который заключается в том, чтобы обернуть вашу логику в цикл повтора: (retryable содержит выборку, изменение, сохранение). Если вы вернетесь к версии VersionError (исключение оптимистического блокирования), вы можете повторно попробовать эту операцию несколько раз и каждый раз получать новую копию. Тем не менее, я по-прежнему предпочитаю атомарные обновления! – Adrian Schneider 15 November 2017 в 18:15

Оператор $ push добавляет указанное значение в массив.

{ $push: { <field1>: <value1>, ... } }

$ push добавляет поле массива со значением как своим элементом.

Выше ответ отвечает всем требованиям, но я получил его, выполнив следующие

var objFriends = { fname:"fname",lname:"lname",surname:"surname" };
Friend.findOneAndUpdate(
   { _id: req.body.id }, 
   { $push: { friends: objFriends  } },
  function (error, success) {
        if (error) {
            console.log(error);
        } else {
            console.log(success);
        }
    });
)
4
ответ дан Parth Raval 15 August 2018 в 16:33
поделиться

Я столкнулся с этим вопросом. Мое исправление заключалось в создании дочерней схемы. См. Ниже пример для ваших моделей.

---- Персональная модель

const mongoose = require('mongoose');
const SingleFriend = require('./SingleFriend');
const Schema   = mongoose.Schema;

const productSchema = new Schema({
  friends    : [SingleFriend.schema]
});

module.exports = mongoose.model('Person', personSchema);

*** Важно: SingleFriend.schema -> обязательно используйте строчные буквы для схемы

--- Схема ребенка

const mongoose = require('mongoose');
const Schema   = mongoose.Schema;

const SingleFriendSchema = new Schema({
  Name: String
});

module.exports = mongoose.model('SingleFriend', SingleFriendSchema);
-1
ответ дан theRealSheng 15 August 2018 в 16:33
поделиться
0
ответ дан KARTHIKEYAN.A 28 October 2018 в 23:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: