2016-09-05 8 views
3

Мой вопрос почти дубликат этого question. Разница в том, что я использую minimongo в рамках платформы/платформы Meteor. Учитывая этот документ:Как обновить свойство в нескольких объектах в массиве для одного документа в коллекции Meteor/minimongo?

{ 
"_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. Изменение данных непосредственно на сервере также является изначально реактивным и выгодным, хотя на самом деле это не обязательно для моего приложения.

Я не совсем уверен, как сформулировать запрос в minimongo.

Я попытался:

Meteor.users.update({_id: 's8Ppj4ZFSeq9X6xC4', 'events.handled.visible': false }, { $set:{'events.$.handled.visible':true} }); 

Это работает только для первого найденного объекта в массиве. Однако я хотел бы обновить все объекты в массиве, где handled.visible является ложным.

+0

Можете ли вы показать нам, что вы пробовали до сих пор? – Shrabanee

ответ

1

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

Сервер:

Добавьте meteorhacks:aggregate пакет для вашего приложения с

meteor add meteorhacks:aggregate 

, а затем использовать в качестве

Meteor.methods({ 
    getInvisibleEventsCount: function(userId){ 
     var pipeline = [ 
      { "$match": { "_id": userId, "events.handled.visible": false } }, 
      { "$unwind": "$events.handled" }, 
      { "$match": { "events.handled.visible": false } }, 
      { "$group": { 
       "_id": null, 
       "count": { "$sum": 1 } 
      }} 
     ]; 
     var result = Meteor.users.aggregate(pipeline); 
     return result; 
    } 
}); 

Клиент:

Meteor.call("getInvisibleEventsCount", userId, function(err, response) { 
    var max = response[0].count; 
    while(max--) { 
     Meteor.users.update(
      { "_id": userId, "events.handled.visible": false }, 
      { "$set": { "events.$.handled.visible": true} } 
     );  
    } 
}); 
+0

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

+1

Этот метод работает. Я протестировал его. Что касается производительности, я проверил другой метод. Я сравню в своем ответе. Благодаря! – saejuro

1

Meteor в настоящее время не позволяет обновлять несколько элементов в массиве. Нужно перебирать массив для обновления для каждого возвращаемого документа.

+0

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

1

Я пробовал 3 метода до сих пор, один из них отправил chridam, который работает.

Chridam's Method

Метод 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 является заменой всех записей независимо от того, верно или false, что является самым простым и самым простым (я знаю, что я указал в своем вопросе только для обновления ложных а для производительности, это решение также представлено).

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/мин
Среднее время отклика - 109ms

Метод Chridam в:
Средняя пропускная - 0,08/мин
Среднее время отклика - 221ms

Метод 1 и Chridam-х почти одинаковы. Но я заметил, что обновления пользовательского интерфейса выполняются быстрее с использованием метода 2, при этом сопоставимая пропускная способность и время отклика. Я просто не уверен, что метод 2 будет лучше, так как больше вызовов методов выполняется.

Любые комментарии для улучшения опубликованных методов или которые могут быть более быстрыми в других обстоятельствах, будут очень оценены.

+0

Отличные тесты! – chridam

+0

Спасибо. Я уверен, что это справедливо с производством. :) – saejuro