MongoDB comparison - database

I am trying to retrieve data in my MongoDB database. If I have the following below in my mongoDB database, I want to select the Password given the Username. So in this case, I will be looking through the database for a Username that is 'e' and retrieving the password associated with that specific Username. I've tried looking everywhere but I can't seem to find a solution on how to do it. I am using express, node, and mongoDB for this personal project. What I have so far is just looking up with database with .find({ Username: Username} and it outputs the entire JSON object.
To clarify, I will be sending a request with a Username of value 'e' and looking it up the database trying to retrieve the value of Password.
{
_id: 62d7712e6d6732706b46094e,
Username: 'e',
Password: 'hi',
__v: 0
}

find takes multiple inputs you can give the select statements also in find itself
so the query will be like
db.collectionName.find({username:'e'},{_id:0,password:1})
mongo by default fetch _id all the time by default so you need to specifically mention to not fetch _id thus _id :0

for such scenarios, there are 2 options if username is unique i would suggest to go with findOne rather then find
db.collectionName.findOne({username:'e'}).password
the same will work if you have multiple records with same username but you want only the first record
but if you want data of all the records as array
db.collectionName.find({username:'e'},{_id:0,password:1})..map( function(u) { return u.password; } )

Related

Query Firestore collection on map

I have database of Workspaces with members and some other data. For each workspace there is a members Map, where key is the UserId and value is the email
It is structured like this:
\Workspace01
--- name:
--- color:
--- members:
------ userid: "email#email.com"
I am trying to query workspaces where the current user is a members.
In Security Rules for instance, I can try something like
allow read if uid in resource.members.keys()
and it works fine (I think). It allows read, etc.
However, if I try to query the same thing, for instance in kotlin/android, it gives a permission error:
collection.whereArrayContains("members.keys", uid )
I have also tried FieldPath.of(), or whereNotEqual("members[uid]", null), still the same thing.
I also tried using emails as keys and uid as values... Obviously no difference
There also was a suggestion of using orderBy("memebers.uid"). That also gives a "bad permission". However, this orderBy query works just fine in the Firebase console
I am completely out of ideas.
Help?
You say that the members field is a map, so it makes sense that you can't query it with whereArrayContains.
If you want to check if the uid subfield has a specific value, that'd be:
collection.whereEqualTo("members.theUidValue", "theEmailValue")
I'm not entirely sure that your security rules will allow this, so I'd start with more relaxed rules to first see if the query works.
If you want to simply check whether the UID exists, that isn't possible on a map structure. To allow that, add an additional array field with just the UID values from the map (e.g. memberUIDs), and then query with whereArrayContains on that.

Mongoose - Can't explain population

I'm doing a certain query, and I want to get the executionTime of it (including the popualtion):
const managerId = "023492745"
const company = await Companies.find({
_id: "1234"
})
.populate(
{
path: "employees",
match: {
_id: { $ne: managerId },
},
})
.explain()
I try to use explain() on the query, but all It only retrieves information about the find() part and not about the populate() part. How can I get the executionTime of the whole query?
explain is a command executed by the mongodb server, while populate is a function executed on the client side by mongoose.
The populate function works by receiving the results of the find from the server, then submitting additional queries to retrieve the corresponding data to place in each document.
The response to the explain command does not contain the found documents, only the statistics and metadata about the query, so there is nothing for populate to operate on.
Instead of explain, you might try increasing the log verbosity or enabling profiling on the mongod server to capture the subsequent queries.

Querying Firestore without Primary Key

I'd like my users to be able to update the slug on the URL, like so:
url.co/username/projectname
I could use the primary key but unfortunately Firestore does not allow any modifcation on assigned uid once set so I created a unique slug field.
Example of structure:
projects: {
P10syfRWpT32fsceMKEm6X332Yt2: {
slug: "majestic-slug",
...
},
K41syfeMKEmpT72fcseMlEm6X337: {
slug: "beautiful-slug",
...
},
}
A way to modify the slug would be to delete and copy the data on a new document, doing this becomes complicated as I have subcollections attached to the document.
I'm aware I can query by document key like so:
var doc = db.collection("projects");
var query = doc.where("slug", "==", "beautiful-slug").limit(1).get();
Here comes the questions.
Wouldn't this be highly impractical as if I have more than +1000 docs in my database, each time I will have to call a project (url.co/username/projectname) wouldn't it cost +1000 reads as it has to query through all the documents? If yes, what would be the correct way?
As stated in this answer on StackOverflow: https://stackoverflow.com/a/49725001/7846567, only the document returned by a query is counted as a read operation.
Now for your special case:
doc.where("slug", "==", "beautiful-slug").limit(1).get();
This will indeed result in a lot of read operations on the Firestore server until it finds the correct document. But by using limit(1) you will only receive a single document, this way only a single read operation is counted against your limits.
Using the where() function is the correct and recommended approach to your problem.

Using Redis to store array of hashes

I have just started to look at Redis and would like to be able to store an Array of hashes, where I can pop a random key/value out and then put it back in when I need to.
So in Ruby I would have something like this
users = [{ username: "user1", password: "password"}, { username: "user2", password: 'password'}]
So if I wanted to get a random key/value object from the Array I would do something like this
#user = users.shuffle!.pop
And then to put it back into the array
users.push(#user)
The idea for using Redis is that I have two processes (Ruby based app) that need to share a pool of users at the same time. Once a process has finished with a user I want it to put it back into the pool.
Could anyone point me in the right direction please
Thanks
You could Redis Hash to store a user info and Redis Set to store all these hashes together.
Steps:
Make a redis Hash with HSET command:HMSET userId_653 username "Tom" password "gd36e3hd38d3jdj3yd3hd38"
Add this hash in the set called users: SADD users userId_653. This set contains all the users.
Get a random user key from the set: SRANDMEMBER users. It will return userId_653
Get the corresponding values from hash using HGET userId_653 username
If you need to pop the key simply do SPOP users after step 3. and SADD again after processing in step 4.
A similar question for better understanding: Redis how to store associative array
References:
http://redis.io/commands/srandmember
http://redis.io/commands/sadd
http://redis.io/commands/spop
http://redis.io/commands/hget
http://redis.io/commands/hmset
PS: I have no experience in Ruby. Look for suitable Redis Ruby API which would support all these operations!

How to filter users by email in Google App Engine?

I tried User(email = email) and User.all().filter('email = ', email).get(), but both of them don't work for me.
Thanks
The right answer is User(email).
You need to construct a User object for the user you want to filter by - I'm assuming here that your model includes a UserProperty. For example:
User.all().filter("user =", User(email)).get()
Failing that, you can denormalize, and store the user's email in an additional StringProperty field.
If you're using the user as the primary key on your entity, though, you'd be better off fetching the user___id from the User object and using it as the key name for the entity when you create it. Then, you can fetch it with User.get(user_id), which is much more efficient than doing a query.
Assuming you're using the Django variant of GAE, try:
User.all().filter(email = email)

Resources