MongoDB : Snapchat like notification schema for the database - mongodb

I've done some research regarding the following subject and I wanted to get advice from more experienced developper to see if my solution was the best one.
If you don't know what Snapchat is, it's a mobile application that let you share pictures with your friends.
What I'am interested in is the notification part of the application, where the user checks if he has received new pictures. It looks like this :
What I want to do is find the best way to check, when the user opens the app or refresh the view, if he has received new images/messages using MongoDB.
After some research the best solution is to have three collections in my Mongo database :
User : User_ID
Username
PasswordHash
...
Where the User_ID is unique and generated by MongoDB
Messages: Message_ID
Message_Content
...
Where the Message_ID is unique and generated by MongoDB. The collection could store other informations like an image URL (images stored in a BLOB), etc.
Notifications : Notification_ID
Sender_ID
Receiver_ID (index)
Message_ID
Where the Notification_ID is unique and generated by MongoDB. The Sender_ID and Receiver_ID are User_ID from the collection User. The Message_ID is from the collection Messages. The Receiver_ID field is indexed.
So when an user launches or refresh the view, I query the collection Notifications with the field Receiver_ID (which is indexed) set to the actual User_ID to find all the messages he may have received. If he has received messages, I query the Messages collection to find all the information about the messages he received (with Message_ID obtained by the previous query one Notifications).
After that, I delete the document(s) on the collection Notifications (if he has not yet opened the messages, I store the Message_ID locally on the device).
To add documents to the Notifications and Messages collections, it is done when an user sends a new message.
The field Receiver_ID from the Notifications collection is indexed to query faster. If I understand correctly indexes with MongoDB, the write operations are a bit slowed down but the reading speed is a lot better. But just to be sure, the Receiver_ID index will be updated automatically when new documents are added to the collection Notifications or I'll have to update it manually ?
Is it the best solution to solve this problem or is there a better one ?
EDIT : There is another question I came accross :
The Receiver_ID field is indexed so I can query faster the Notifications collections. Doing so let me get the Message_ID but after that, I need to query the Messages collection in order to retrieve all the information regarding the message. Should I also index the field Message_ID in the collection messages, knowing that this collection will store all the messages ever sent and it could take some time to find the corresponding message ?
Or is the field _id is automatically indexed by Mongo so I wouldn't need to do that ?
EDIT 2 : Regarding the question from the second EDIT, I found out that I don't need to index the Message_ID because all _id are indexed by default.
MongoDB creates the _id index, which is an ascending unique index on the _id field, for all collections when the collection is created. You cannot remove the index on the _id field.
You can learn more about it here
Thanks for reading !
Here are some links I found when looking for a solution :
Develop Database Schema for Notify like facebook
How to implement instant notification system using Express + Mongo Rest API?
Is it better to store notifications of all users under one collection / table OR rather provide each user his own collection / table to store notifications?

the research provided looks impressive!
Regarding notification process - looks OK - but what if user uses more than one device (tablet, phone etc?) - that need to include device ID and status array per device
Index once created will be maintained by DB engine

Related

Firebase Firestore query by document id using swift

I am trying to query my database to get all the users where the document id is equal to the users id. I know that I can add that id as a field into the document, but I'd like to optimize the memory I take up, so I'd prefer accessing the document id directly through. Something like
.whereField(DOCUMENT_ID, isEqualTo, User.id)
DOCUMENT_ID is not a valid field so far as I know, and I don't know the equivalent. I have read around that other languages modules have a workaround like
.whereField(Firebase.firestore.FieldValues.documentId(), isEqualTo, User.id)
but I've heard hide nor hair of that in swiftUI. Any ideas?
To filter on the document ID in a query, you can use FieldPath.documentID() in Swift too: https://firebase.google.com/docs/reference/swift/firebasefirestore/api/reference/Classes/FieldPath#/c:objc(cs)FIRFieldPath(cm)documentID. But if you do this in a single document, that'd be the same as just doing document(User.id).

Mongoose how to stop using _id (don't store it) and use id instead

Since I will be listing my full database on /bots, and I want to use id instead of _id (discord uses id for everything, so I'm accustomed with id and not _id)
I don't even want to save id as _id in the database. So any idea what to do?
This is not possible!
MongoDB automatically creates an _id for every document that gets inserted into a database.
This is there in order to give you a one-to-one value that you will be able to use to identify each document.
The id also contains a timestamp to when you inserted the document which then can be used to optimize queries using indexes.
This is also a best practice to send the _id to the user (even if it's mapped to an id field) to then be able to query more efficiently and also to not expose their Discord Id to everyone.
Hope I could answer your question.
You could read more about it here:
https://docs.mongodb.com/manual/core/document/#the-id-field
How to remove _id in MongoDB and replace with another field as a Primary Key?

Does length of indexed field matter while searching?

The chat app schema that I have is something like below.
1. conversations {participants[user_1, user_2], convsersation_id}
2. messages {sender: user_1, sonversation_id, timestamps}
I want to map this relationship using existing _id:ObjectId which is already indexed.
But if I want to get all conversation of user_1 I have to first search in which conversation that user is involed and get that conversation's _id and again search for the messages in messages using that conversation _id.
So my questions are -
Does length of indexed field (here _id) matters while searching?
Should I create another shorter indexed fields?.
Also if there is any better alternative schema please suggest.
I would suggest you to maintain the data as sub documents instead of array. The advantage you have is you can build another index (only) on conversation_id field, which you want to query to know the user's involvement
When you maintain it as array, you cannot index the converstaion_id field separately, instead you will have to build a multi key index, which indexes all the elements of the array (sender and timestamps fields) which you are never going to use for querying and it also increases the index size
Answering you questions:
Does length of indexed field (here _id) matters while searching? - Not really
Should I create another shorter indexed fields? - Create sub-document and index converstaion_id
Also if there is any better alternative schema please suggest. - Maintain the array fields as sub-documents

create unique id in mongodb from last inserted id using pymongo

Is there a way I can find the last inserted document and the field, i.e. _id or id such that I can increment and use when inserting a new document?
The issue is that I create my own id count, but I do not store this, now I've deleted records, I cannot seem to add new records because I am attempting to use the same id.
There is no way to check insertion order in MongoDB, because the database does not keep any metadata in the collections regading the documents.
If your _id field is generated server-side then you need to have a very good algorithm for this value in order to provide collision avoidance and uniqueness while at the same time following any sequential constraints that you might have.

Mongodb query which avoid duplicates items with different _id

I'm working with dump of events provided by 3rd party side. And in this dump they have duplicates events, which is fully identical, but have different _id. So my goal is to provide unique only data, so I can't use duplicates event.
Is it possible to build the query which return me only documents with unique value?
Lets say, in each document i have EventId field, and I need all the events, with unique EventID
I can't change dump, have only read permission to it.
You can use db.collection.distinct() method http://docs.mongodb.org/manual/reference/method/db.collection.distinct/