NoSQL 'like' model structure

I've had some relational database experience, but I am quite new to NoSQL databases. I am trying to do the following (in Firebase Firestore) I have a collection of user documents and a collection of item documents.
A user has to be able to Like an item. My relational database thinking mind shifts towards a structure where the ID of the user document and the ID of the item are saved in a table, but this wouldn't work in a NoSQL Database.

Without going into the details of the none working solution I came up, I was wondering if anyone here has a solution? I want to be able to get all liked items for a specific user without 100s of round trips to the server.

Edit @Jesús Fuentes: multiple users should be able to like the same item

Upvotes: 1

Views: 883

Answers (2)

Eventually thanks to the help of @Geoff and @Egghead I managed to do it as followed:
Every Item has a Likedby Array with key:bool pairs, where the key is the userID and the bool is set to true if the user liked the item (adding all the other users with false isn't necessary). According to The Firebase Docs this is the needed, because an array of just the strings of userID's can't be queried.

example:

{
item: "Stackoverflow",
likedBy: {
    "Egghead": true,
    "Geoff": true,
    "f5172c0d83892c41b60de3f1fadd89": true
}

This can then be query using (Swift, see docs for other languages):

db.collection("posts")
             .whereField("likedBy.Egghead", isEqualTo: true)
                         .getDocuments() { (querySnapshot, err) in

    // do what you have to do

}

Upvotes: 1

Geoff
Geoff

Reputation: 438

Lets say you have a user document in your users collection, user1. user1 sees an item that he likes, so he "likes" that item. In the user1 document, a new collection is made, likedItems. In this user's likedItems collection, a document is added with the ID of the liked item, for example, 0001.

Now if you want to get all liked items for a specific user, you just have to grab all documents from their likedItems collection.

The concept is the same for any language, but here's a JavaScript example:

db.collection(`users/${userId}/likedItems`).get().then(snapshot => {
  snapshot.forEach(doc => {
    // doc is the document for a liked item
   ...
  }
}

Upvotes: 2

Related Questions