Мой вопрос почти дублирует этот вопрос. Разница в том, что я использую 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.

3
saejuro 5 Сен 2016 в 11:46

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 лучше, поскольку выполняется больше вызовов методов.

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

1
Community 23 Май 2017 в 11:51

В настоящее время Meteor не позволяет обновлять несколько элементов в массиве. Чтобы обновить каждый возвращенный документ, необходимо выполнить цикл по массиву.

1
Vinay Prabhakaran 6 Сен 2016 в 03:09