Set new field in array of array

Hello,

I’m using Meteor and Mongodb.

Considering the data structure:

{
  "_id": "myid",
  "userId": "currentuserid",
  "username": "myuser",
  "app": {
    "twitter": [],
    "rss": [
      {
        "url": "https://www.example1.com/rss",
        "_id": "id1site1",
        "feed": [ 
          { "data": "this is article 31267218", "guid": { "_text": "31267218" } },
          { "data": "this is article 31259997", "guid": { "_text": "31259997" } }
        ]
      },
      {
        "url": "https://www.example2.com/rss",
        "_id": "id2site2",
        "feed": [
          { "data": "this is article 44446355", "guid": { "_text": "44446355" } },
          { "data": "this is article 44433222", "guid": { "_text": "44433222" } }
        ]
      }
    ]
  }
}

For example, _id=“id2site2” and guid=“44446355” as parameter,

i’m using this command:

  let distinct = await UsersAppDB.rawCollection().distinct("app.rss.feed", 
  { 
    "userId": "currentuserid",
    "app.rss._id": "id2site2",
    "app.rss.feed.guid._text": { $eq: "44446355" }
  }
  )

but this doesn’t return the correct result.

i would like to return this:
{ "data": "this is article 44446355", "guid": { "_text": "44446355" } },

Next is to set a new field {visible: true} in this part of the data:
{ "data": "this is article 44446355", "guid": { "_text": "44446355" }, visible: true },

How to update the data?

Thank you for helping

First part of the answer:
I could retrieve the data part using $unwind and $replaceRoot successively to access the part of the data i’m interested using:

let guidSelection = await UsersAppDB.rawCollection().aggregate([
  { $match: { "userId": Meteor.userId()} },
  { $unwind: '$app.rss' },
  { $replaceRoot: { newRoot: '$app.rss' } },
  { $match: { 'url': url } },
   { $unwind: '$feed' },
  { $match: { 'feed.guid._text': guid } },
  { $set: { 'feed.visibility': !visibility } },
]).toArray()

I just need to use update function, as aggregate doesn’t mutate the data in the Collection.

I’ll update this as soon i find out how.

let aggregate = await UsersAppDB.rawCollection().aggregate([
  { $match: { "userId": Meteor.userId()} },
  { $match: { 'app.rss.url': url } },
  { $match: { 'app.rss.feed.guid._text': guid } },
  { $set: { 'app.rss.feed.visibility': !visibility } },
  { $merge: 'userappdb' }

considering that userappdb is the name of your collection,
this command here doesn’t work exactly. as it create the field “visibility” is all feed array, instead of only where the array contains the matching guid.

I can’t find out how to edit a post. If i manage to i’ll compress my answers to one, but i’m still looking for the correct update request to update that part of the data.

Finally!
Here was the answer. Without using aggregate, merge, unwind, replaceroot or anything.
Just using this query operator that contains the [array] name in brackets preceding by the array name 'app.rss.$.array.$[array].fieldToUpdate


let aggregate = await UsersAppDB.update({
  "userId": Meteor.userId() , 'app.rss.url': url},
  {
     $set: {
          'app.rss.$.feed.$[feed].visibility': !visibility
         } 
  }, 
  {
    arrayFilters: [{
      "feed.guid._text": guid,
    }]
  }
)
2 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.