Как сделать upsert / push с монгоидом / мопедом
Я использую Mongoid (v3) для доступа к MongoDB и хочу выполнить это действие:
db.sessionlogs.update(
{sessionid: '12345'}, /* selection criteria */
{'$push':{rows: "new set of data"}}, /* modification */
true /* upsert */
);
Это прекрасно работает в оболочке монго. Это также именно то, что я хочу, так как это единственная атомарная операция, которая важна для меня, так как я буду часто ее называть. Я не хочу делать две операции - выборку, а затем обновление. Я пробовал кучу вещей через mongoid, но не могу заставить его работать.
Как я могу получить MongoID с пути и просто отправить эту команду в MongoDB? Я предполагаю, что есть какой-то способ сделать это на уровне мопедов, но документации этой библиотеки в основном не существует.
3 ответа
[Ответ найден при написании вопроса...]
criteria = Sessionlogs.collection.find(:sessionid => sessionid)
criteria.upsert("$push" => {"rows" => datarow})
Вот один из способов сделать это:
session_log = SessionLog.new (session_id: '12345') session_log.upsert session_log.push (: строки, "новый набор данных")
Или другой:
SessionLog.find_or_create_by (session_id: '12345'). push (: строки, "новый набор данных")
#push
выполняет атомную $push
на поле. Это объясняется на странице " Атомная стойкость".
(Примечание: в примерах используются UpperCamelCase и snake_case, как это принято в Ruby.)
Пока не переходите к мопеду, вы можете использовать операцию поиска и изменения для достижения того же результата (со всеми полезными функциями по умолчанию для области видимости и наследования)
Пример сохранения ребра на графике, если он не существует
edge = {source_id: session[:user_id],dest_id:product._id, name: edge_name}
ProductEdge.where(edge).find_and_modify(ProductEdge.new(edge).as_document,{upsert:true})