I have a list of user ids stored in a field of MongoDB collection. Each of the user ids is an UUID. The field is an array. For example,
["59cc7562-751b-11ed-a1eb-0242ac120002", "66e6f240-751b-11ed-a1eb-0242ac120002",
"742df8ea-751b-11ed-a1eb-0242ac120002", ............,"6cf6e398-751b-11ed-a1eb-0242ac120002"]
Now, if I want to check whether a user id is in the array, i need to do loop through the array until I find the user id or reach the end of the array. This is slow. I wonder if I can use a set to store the user ids instead of an array.
I am using Next.Js in the backend. If I convert the array to a set, that would be even slower than just looping through the array since the conversion takes o(n).
Related
In Firestore security rules, is there any way to check a condition for every value in an array?
I have a document that has a subcollection. The document has an order field which is an array of IDs of documents in the subcollection; this array defines a custom user-defined order for those documents.
I want a security rule that checks that any values added to the order array correspond to a document in the subcollection (i.e. that the document exists). That is, it needs to check this condition for every value in the array.
What you call an array is known as a List in Firestore security rules, and there are no list comprehension style operations beyond the has* checks for literal values.
The problem is that such a looped check would quickly become a performance (and cost) bottle neck.
i have created an array of strings "challengeMember" in Firestore database and i want to add data to it when user clicks a button, my database:
in my code am trying to update the array, every time user join a challenge, the challenge name will be added to this array i know how to access the array using:
FirebaseFirestore.instance.collection("Users").doc(user!.uid).update({'challengeMember': widget._challengeName});
but the problem with this it is not specifying the array index and it is not checking whether the index is empty or not, so how can i dynamically access this array and keep adding values.
Firestore has a special trick to add an array, and it goes like this:
await FirebaseFirestore.instance.collection('users').doc(uid).update({
'tokens': FieldValue.arrayUnion([token]),
});
See the FieldValue documentation on how to manipulate arrays.
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
I know that in Mongo, when you create IDs, the IDs are created in part by a time element which can be nice for sorting without using any other keys like createdAt or updatedAt. Is the same true for IDs created in Parse?
Parse-server doesn't use deterministic IDs for the object but 10 characters random strings (which can be configured on your side also if you wish to have longer objectIds)
https://github.com/parse-community/parse-server/blob/master/src/cryptoUtils.js#L39
I need to get the users whose ids are contained in an array. For this i'm using the $in operator, however being this inside an aggregate operation, i'd like to get back a specific user all the time it's id is present in the array, not just one. For example:
The ids array is A=[a,b,c,b] and U(x) is user with id x
with users.find({_id:{$in:A}}) i get these users as result: U(a),U(b),U(c)
instead i'd like to get back the result: U(a),U(b),U(c),U(b)
so get the user back every time it's id appears.
I understand that $in is working as expected but does anyone have an idea on how can i achieve this?
Thanks
This isn't possible using a MongoDB query.
MongoDB's query engine iterates over the documents in a collection (or over an index if there's a useful one) and returns to you any documents that match your query, in the order it finds them. Whether b appears once, twice, or a hundred times in your query makes no difference: the document with _id of b matches the query and is returned once, when MongoDB finds it.
You can do a post-processing step in your programming language to repeat documents as many times as you want.