Агрегация вложенных документов MongoDB с использованием событий изменения - PullRequest
0 голосов
/ 17 апреля 2020

Проблема в том, что когда я помещаю sh новый документ в поле массива, он становится пунктирной.

Я пытаюсь добиться фильтрации ответа на изменение Событие или Collection.watch ().

This the okay version

Но это происходит

enter image description here

Нет способа получить доступ к updateDescription.updatedFields.message, поскольку он стал точечной нотацией.

Я пытался использовать

var filter = [{
    $match: {
        $and: [
            { 'documentKey._id': req.body.id },
            {'updateDescription.updatedFields.message': // value of current length of the messages array}
        ]
    }
  }];

и

var filter = [{
    $match: {
        $and: [
            { 'documentKey._id': req.body.id },
            {'updateDescription.updatedFields.messages' : {$exists: true}}
        ]
    }
  }];

Я также использовал проекцию:

try{
    res.status(200).set({
      "connection":"keep-alive",
      "cache-control": "no-cache",
      "content-type":"application/json"
    });
  var query = await User.findOne({'_id': req.body.id});
  var len = parseInt(query['messages'].length);
  var _str = 'messages.'+String(len);
  console.log(_str)
  var project = [{$project: {'updateDescription.updatedFields' : {$objectToArray: '$updateDescription.updatedFields'}}}]
  var filter = [{
    $match: {
        $and: [
            { 'documentKey._id': req.body.id },
            {'updateDescription.updatedFields.k': _str}
        ]
    }
  }];

  await User.watch(filter, project).on('change', data => console.log(data))

  }catch(err){
    res.status(500).send(err);
  }

Но до сих пор у меня нет никакого решения, как решить эту проблему.

Ответы [ 2 ]

0 голосов
/ 19 апреля 2020

Проблема в том, что вы проецируете это неправильно.

$project: {'updateDescription.updatedFields' : {$objectToArray: '$updateDescription.updatedFields'}}

должно быть

{$project: { 'updateDescription.updatedFields' : {$objectToArray: '$updateDescription.updatedFields'}, 'documentKey._id': req.body.id  }}

Тогда вы go используете регулярное выражение для $ match

{$match: {
    $and: [
       { 'documentKey._id': req.body.id },
       {'updateDescription.updatedFields.k': {$regex:"^matches"}}
   ]}

Вот полный рабочий фрагмент:

  try{
    res.status(200).set({
      "connection":"keep-alive",
      "cache-control": "no-cache",
      "content-type":"application/json"
    });

  var filter = [
    {$project: { 'updateDescription.updatedFields' : {$objectToArray: '$updateDescription.updatedFields'}, 'documentKey._id': req.body.id  }},
    {$match: {
        $and: [
            { 'documentKey._id': req.body.id },
            {'updateDescription.updatedFields.k': {$regex:"^matches"}}
        ]
    }
  }];

  await User.watch(filter).on('change', data => console.log(data.updateDescription.updatedFields))

  }catch(err){
    res.status(500).send(err);
  }

Причина, по которой он не совпадает, заключается в том, что вы используете оператор $ и, и нет «documentKey._id» для сопоставления, так как вы спроецировали его неправильно.

0 голосов
/ 18 апреля 2020

Этапы $filter и $project должны быть вместе в одном массиве. Функция watch принимает (Массив конвейера, Объект параметров). Попробуйте:

  var filter = [
    {$project: {'updateDescription.updatedFields' : {$objectToArray: '$updateDescription.updatedFields'}}},
    {$match: {
        $and: [
            { 'documentKey._id': req.body.id },
            {'updateDescription.updatedFields.k': _str}
        ]
    }
  }];

await User.watch(filter).on('change', data => console.log(data))

...