1
user schema:

{
  _id: "OjectId",
}
interaction schema:

{
    blocker_id: user_id_x
    blocked:  { 
        user_id_y: true, 
        user_id_z: true,
        etc...
     }
}
                db.user.aggregate([{
                  $lookup: {
                    from: "interaction",
                    as: "remove",
                    let: { tar_id: "$_id" },
                    pipeline: [
                      {
                        $match: {
                          [`blocked[$$tar_id]`]: true,
                        },
                      },
                      {
                        $limit: 1,
                      },
                      {
                        $project: {
                          _id: 0,
                          remove: "true",
                        },
                      },
                    ],
                  },
                }]}

Notice the line:

  [`blocked[$$tar_id]`]: true,

Does the above lookup work? If not, how can I get it to work as intended?

The reason for this schema design is because looking up the value of an object’s property is O(1), while looking up an element of an array is O(N). Huge difference. Any solution must maintain the O(1) time complexity of the query.

EDIT:

tested. It does not work. The problem remains, how do I get to work as desired?

1 Answers1

0

One option is:

db.user.aggregate([
  {$lookup: {
      from: "interaction",
      as: "remove",
      let: {tar_id: {$toString: "$_id"}},
      pipeline: [
        {$match: {
            $expr: {
              $gt: [
                {$size: {
                    $filter: {
                      input: {$objectToArray: "$blocked"},
                      cond: {$eq: ["$$tar_id", "$$this.k"]}
                    }
                }},
                0
              ]
            }
        }},
        {$limit: 1},
        {$project: {_id: 0, remove: "true"}}
      ]
    }
  }
])

See how it works on the playground example

nimrod serok
  • 14,151
  • 2
  • 11
  • 33
  • This doesn't seem efficient. The reason why I chose not to store the blocked users as an array is because looking up a property of an object is much faster than finding an element in an array. Is there another option? – Bear Bile Farming is Torture Jan 09 '23 at 08:36
  • Is there another option where O(1) time complexity is maintained? – Bear Bile Farming is Torture Jan 09 '23 at 20:21
  • "because looking up a property of an object is much faster than finding an element in an array" Why do you think so? When you create an index on an array then MongoDB indexes every element from the array. I would expect similar speed. – Wernfried Domscheit Jan 09 '23 at 21:17