Reputation: 23
The problem is that when I push a new document inside the array field it becomes a dotted notation.
What I am trying to achieve is to filter the the response of the Change Event or the Collection.watch().
But this happens
There is no way that I can access the updateDescription.updatedFields.message because it became a dot notation.
I tried to use
var filter = [{
$match: {
$and: [
{ 'documentKey._id': req.body.id },
{'updateDescription.updatedFields.message': // value of current length of the messages array}
]
}
}];
and
var filter = [{
$match: {
$and: [
{ 'documentKey._id': req.body.id },
{'updateDescription.updatedFields.messages' : {$exists: true}}
]
}
}];
I also used projection:
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);
}
But still I haven't got any solution how to solve this.
Upvotes: 1
Views: 611
Reputation: 193
The problem is that you are projecting it wrong.
$project: {'updateDescription.updatedFields' : {$objectToArray: '$updateDescription.updatedFields'}}
is should be
{$project: { 'updateDescription.updatedFields' : {$objectToArray: '$updateDescription.updatedFields'}, 'documentKey._id': req.body.id }}
Then you go use regex on the $match
{$match: {
$and: [
{ 'documentKey._id': req.body.id },
{'updateDescription.updatedFields.k': {$regex:"^matches"}}
]}
Here's the full working snippet:
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);
}
The reason why it's not matching is because you are using $and operator and there's no "documentKey._id" to match with since you projected it wrong.
Upvotes: 2
Reputation: 28336
The $filter
and $project
stages should be together in a single array. The watch
function takes (Pipeline Array, Options Object). Try:
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))
Upvotes: 0