'Mongoose - "Enriched" Query with Data from other Collection
I'm quite new to using Mongoose and therefore not too familiar with operations that go beyond finding data in a single collection. Was googling approaches to achieve what I want to for days now, and thought it might be an idea to reach out to this community for a little help.
So here's my situation: I have 2 models, Artwork and UserInteraction:
const artworkSchema = new mongoose.Schema({
slug: {type: String, unique: true},
title: {type: String},
content: {type: String},
})
const Artwork = mongoose.model("Artwork", artworkSchema)
const userInteractionSchema = new mongoose.Schema({
uid: {type: String}, // Firebase User ID
action: {type: String, enum: ["LIKED", "FOLLOWED"]},
targetType: {type: String, enum: ["ARTWORK", "GALLERY"]},
targetKey: {type: String, enum: ["SLUG", "CODE"]},
targetValue: {type: String}, // slug of liked/followed artwork, code of liked/followed gallery
created: {type: Date, default: () => new Date()},
})
const UserInteraction = mongoose.model("UserInteraction", userInteractionSchema)
The logic is that whenever a user does the action of "liking an artwork", a new UserInteraction is created:
const newUserInteraction = {
uid: "MyFirebaseUserId", // This user ..
action: "LIKED", // .. liked ..
targetType: "ARTWORK", // .. an artwork ..
targetKey: "SLUG", // .. based on the artwork's slug, ..
targetValue: "Artwork1Slug" // .. which is 'ArtworkSlug1'
// created will be set to now automatically (see UserInteraction schema)
}
// .. insert into DB
I would like to find a performant query that returns different results for different Firebase User IDs, it should basically
- find all artworks in database (could be in the 100.000s),
- find all user interactions with the criteria
{
uid: "MyFirebaseUserId",
action: "LIKED" ,
targetType: "ARTWORK",
targetKey: "SLUG"
}
// in the example, this would return just one single entry, but in a real life scenario this could return hundreds of results:
[
{
uid: "MyFirebaseUserId",
action: "LIKED",
targetKey: "ARTWORK",
targetKey: "SLUG",
targetValue: "Artwork1Slug", // slug of the liked artwork
created: Fri Apr 29 2022 10:50:45 GMT+0200 (Central European Summer Time)
}
]
- add the
createdvalue (if it exists for a given artwork) to the artworks returned in the first step, - sort the resulting "enriched" artworks by this
createdvalue (highest values first, a.k.a. "last liked artworks" first, non-liked artworks last) - respect a skip and limit value for the final output. I think it's important to do this in the query directly to improve performance.
I would be very thankful for anything that points me into the right direction with this!
EDIT: I've added this Mongo Playground snippet to illustrate my troubles.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
