2

Context:

My database has two collections: "Users" and "Files".

Sample document from "Users" collection:

{
  "username":"Adam",
  "email":"[email protected]",
  "IdFilesOwned":[1,3],
}

As you can see, Adam currently owns two files on the server. Their ids are 1 and 3.

Sample documents from "Files" collection:

{
  "fileId":1,
  "name":"randomPNG.png"
}
{
  "fileId":2,
  "name":"somePDF.pdf"
}
{
  "fileId":3,
  "name":"business.pdf"
}

As you can see, I have three documents on my server, each document having an id and some metadata.

Now, Adam wants to see all the files that he owns, and their metadata. The way i would implement this, is:

1.Lookup the array of file ids that Adam owns.

2.Have node.js run through each id (using a for each loop), and query the metadata for each id.

The problem is that nodejs will make multiple queries (1 query per id). This seems very inefficient. So my question is if there is a better way to implement this?

4
  • What driver are you using? Also, why don't you just store the Files in the Users collection (instead of IdFilesOwned, just FilesOwned)?
    – c1moore
    Commented Jan 3, 2020 at 23:19
  • @c1moore i dont store the files with the users because i want to add the ability to share the files with other users (similar to google drive). Also im using nodejs driver 3.4 Commented Jan 3, 2020 at 23:23
  • You could use an MongoDB's aggregation pipeline. I'll try to type up a better answer, but you can use that to get you started.
    – c1moore
    Commented Jan 3, 2020 at 23:25
  • Thanks. Ill check it out Commented Jan 3, 2020 at 23:26

2 Answers 2

3

You can use the $in operator find more info here So it will look something like this.

db.collection('files').find({ fileId: { $in: [<value1>, <value2>, ... <valueN> ] } })

This is more efficent than lookup for sure. Good luck.

2

I don't have much experience using the driver directly, but you should be able to do the equivalent of the following

db.users.aggregate([
  {
    $lookup: {
      from: "files",
      localField: "IdFilesOwned",
      foreignField: "fileId",
      as: "files"
    }
  }
]);

Not the answer you're looking for? Browse other questions tagged or ask your own question.