Мой вопрос почти дублирует этот вопрос. Разница в том, что я использую Minimongo в рамках / платформе Meteor. Учитывая этот документ:
{
"_id" : ObjectId("4d2d8deff4e6c1d71fc29a07"),
"user_id" : "714638ba-2e08-2168-2b99-00002f3d43c0",
"events" : [
{
"handled" : {
"name": "Mike",
"visible": false
},
"profile" : 10,
"data" : "....."
}
{
"handled" : {
"name": "Shaun",
"visible": false
},
"profile" : 10,
"data" : "....."
}
{
"handled" : {
"name": "Glen",
"visible": true
},
"profile" : 20,
"data" : "....."
}
]}
Как мне запросить конкретный user
и update
все объекты в массиве событий ТОЛЬКО, где 'handled.visible':false to 'handled.visible':true
? Насколько это возможно, я хотел бы получить его в одном запросе. Моя цель действительно улучшить производительность моего приложения. Вместо того, чтобы извлекать весь массив объектов, обрабатывать их на стороне клиента (изменять свойства объекта), а затем повторно обновлять на сервере, было бы здорово выполнить обновление напрямую через Mongo. Изменение данных непосредственно на сервере также является изначально реактивным и выгодным, хотя для моего приложения в этом нет необходимости.
Я не совсем уверен, как сформулировать запрос на минимонго.
Я пытался:
Meteor.users.update({_id: 's8Ppj4ZFSeq9X6xC4', 'events.handled.visible': false }, { $set:{'events.$.handled.visible':true} });
Это сработало только для первого объекта, найденного в массиве. Однако я хотел бы обновить все объекты в массиве, где handled.visible имеет значение false.
2 ответа
До сих пор я пробовал 3 метода, один из которых опубликован chridam, который работает.
Метод 1 просто обрабатывает его в клиенте, но выборочно выбирает только ложные записи:
testLocalAggregate : function(){
var findQuery = Meteor.users.findOne(Meteor.userId(), {fields:{'events':1}}).events;
var tempArr = [];
_.each(findQuery, function(event, index){
if(events.handled.visible === false){
tempArr.push(index);
}
});
if(tempArr.length){
var count = tempArr.length;
while(count --){
Meteor.users.update(
{ "_id": Meteor.userId(), "events.handled.visible": false },
{$set:{'events.$.handled.visible':true}}
);
}
}
}
Метод 2 заключается в замене всех записей, независимо от того, являются ли они истинными или ложными, что является наиболее простым и понятным (я знаю, что в своем вопросе я указал только на обновление ложных записей, но для повышения производительности это решение также представлен).
testUpdate : function(){
var events = Meteor.users.findOne(Meteor.userId(), {fields:{'events':1}}).events;
_.each(events, function(event, index){
if(events.handled.visible === false){
events.handled.visible = true;
}
});
Meteor.users.update({_id : Meteor.userId()}, {$set: {'events': events}});
}
Согласно тестированию в Kadira с 5 вызовами методов, средняя пропускная способность и время отклика следующие:
Способ 1:
Средняя производительность - 0,08 / мин
Среднее время отклика - 219мс
Способ 2:
Средняя пропускная способность - 0,12 / мин
Среднее время отклика - 109мс
Метод Хридама:
Средняя производительность - 0,08 / мин
Среднее время отклика - 221 мс
Метод 1 и метод Хридама почти одинаковы. Но я заметил, что при использовании метода 2 обновления пользовательского интерфейса выполняются быстрее, при этом производительность и время отклика остаются сопоставимыми. Я просто не уверен, будет ли метод 2 лучше, поскольку выполняется больше вызовов методов.
Будем очень признательны за любые комментарии, которые помогут улучшить опубликованные методы или которые могут быть быстрее в других обстоятельствах.
В настоящее время Meteor не позволяет обновлять несколько элементов в массиве. Чтобы обновить каждый возвращенный документ, необходимо выполнить цикл по массиву.
Похожие вопросы
Связанные вопросы
Новые вопросы
mongodb
MongoDB - это масштабируемая, высокопроизводительная база данных NoSQL с открытым исходным кодом, ориентированная на документы. Он поддерживает большое количество языков и платформ разработки приложений. Вопросы по администрированию сервера можно задать на https://dba.stackexchange.com.