MongoDB : find all entries with one key - mongodb

I am trying to use mongoDB on a new project.
I have this documents in my database :
{ "_id" : ObjectId("ID"), "local" : { "rank" : "null", "password" : "PASSWORD", "email" : "EMAIL" }, "__v" : 0 }
{ "_id" : ObjectId("ID"), "local" : { "rank" : "admin", "password" : "PASSWORD", "email" : "EMAIL" }, "__v" : 0 }
{ "_id" : ObjectId("ID"), "local" : { "rank" : "null", "password" : "PASSWORD", "email" : "EMAIL" }, "__v" : 0 }
I want to find all documents with a null rank.
So I test :
db.users.find({local:{rank:"null"}})
But it doesn't work.
If I test with the command :
db.users.find({"local":{ "rank" : "null", "password" : "PASSWORD", "email" : "EMAIL" }})
It works. Why it doesn't work with the first command ?

Both comparisons you are doing against document. The second one works it matches document local.
To compare specific field inside the document you have to use dot notation.
db.users.find({"local.rank":"null"}).
More about how to query embedded document. https://docs.mongodb.com/manual/core/document/#embedded-documents

Related

mongodb find $elemMatch with Multiple Fields

everyone. I need your help. For a script I have to search for users by their ldap id, but I have the problem that I get no output when searching.
a user has the following output.
db.users.find({"name" : "John Sample"} ).toArray()
[
{
"_id" : "testid",
"createdAt" : ISODate("2017-05-11T13:49:35.125Z"),
"services" : {
"password" : {
"bcrypt" : ""
},
"ldap" : {
"id" : "12345678",
"idAttribute" : "uid"
},
"resume" : {
"loginTokens" : [ ]
}
},
"username" : "john",
"emails" : [
{
"address" : "john.sample#test.com",
"verified" : true
}
],
"type" : "user",
"status" : "offline",
"active" : true,
"name" : "John Sample",
"_updatedAt" : ISODate("2018-07-05T18:44:22.061Z"),
"roles" : [
"user"
],
"ldap" : true,
"lastLogin" : ISODate("2018-07-05T10:33:00.712Z"),
"statusConnection" : "offline",
"utcOffset" : 2,
"statusDefault" : "offline"
}
]
I used this command but without success.
db.users.find({"services" : {"$elemMatch": {"ldap" : {"$elemMatch": {"id" : "12345678"}}}}}} ).toArray();
[ ]
$elemMatch is used to find elements that match criteria in an array. But services is an document (sub document), not an array. Just use dot notation to query :
db.users.find({"services.ldap.id":"12345678"})

find and replace string in all mongodb collections

I have a mongodb database named "eagle" and am trying to replace all email records of "blue#domain.com" with "pink#domain.com" (within collection "all collections".
db.eagle.find({}).forEach(function(e,i) {
e.email=e.email.replace("//blue#domain.com","//pink#domain.com");
db.eagle.save(e);
});
I am very new to mongodb...so I'm not even sure that I'm in "eagle" or "falcon"....I just run mongo. This query doesn't do anything.
Here is what my Communications object looks like:
{
"_id" : ObjectId("redacted"),
"timestamp" : ISODate("2016-08-03T15:08:07.000Z"),
"thread_index" : "",
"updated_at" : ISODate("2016-09-01T17:49:31.401Z"),
"from" : {
"username" : "None",
"name" : "Pinky Jones",
"email" : "blue#domain.com"
},
"to" : {
"username" : "redude",
"name" : "Red Baron",
"email" : "red#domain.com"
},
"created_at" : ISODate("2016-09-01T17:49:31.401Z"),
}
Use findAndModify instead find
Documentación findAndModify

How to get a list of nested object only if condition match in mongodb?

I am developing application which had company and there are 2 users reviewer & admin inside that company. Now as a super admin I want to display only Reviewer of the all company. with following information
Company Name,
Reviewer Name,
Reviewer Email
My collection is
{
"_id" : ObjectId("58830988b9c5f808fc307ec4"),
"createdat" : ISODate("2017-01-21T07:11:04.218+0000"),
"isActive" : true,
"users" : [
{
"_id" : ObjectId("58830988b9c5f808fc307ec5"),
"createdat" : ISODate("2017-01-21T07:11:04.219+0000"),
"role" : "admin",
"password" : "test",
"email" : "email3#email.com",
"name" : "test"
},
{
"name" : "test",
"email" : "email2#email.com",
"password" : "test",
"role" : "admin",
"createdat" : ISODate("2017-01-21T07:24:42.559+0000"),
"_id" : ObjectId("58830cba24ebfa04f812e544")
},
{
"name" : "test",
"email" : "email1#email.com",
"password" : "test",
"role" : "admin",
"isActive" : true,
"createdat" : ISODate("2017-01-21T07:36:37.337+0000"),
"_id" : ObjectId("58830f85d92f1808e0984306")
},
{
"name" : "reviewName 1",
"email" : "reviewName1#gmail.com",
"password" : "test",
"role" : "reviewer",
"isActive" : true,
"createdat" : ISODate("2017-01-21T07:55:39.727+0000"),
"_id" : ObjectId("588313fba001380a383e077e")
},
{
"name" : "test",
"email" : "test",
"password" : "test",
"role" : "admin",
"isActive" : true,
"createdat" : ISODate("2017-01-21T07:56:52.963+0000"),
"_id" : ObjectId("588314447bbc230c306804c1")
}
],
"companyname" : "Test Company 1",
"__v" : NumberInt(0)
}
{
"_id" : ObjectId("58830988b9c5f808fc307ec4"),
"createdat" : ISODate("2017-01-21T07:11:04.218+0000"),
"isActive" : true,
"users" : [
{
"_id" : ObjectId("58830988b9c5f808fc307ec5"),
"createdat" : ISODate("2017-01-21T07:11:04.219+0000"),
"role" : "admin",
"password" : "test",
"email" : "test4#email.com",
"name" : "test"
},
{
"name" : "test",
"email" : "test3#email.com",
"password" : "test",
"role" : "admin",
"createdat" : ISODate("2017-01-21T07:24:42.559+0000"),
"_id" : ObjectId("58830cba24ebfa04f812e544")
},
{
"name" : "test",
"email" : "test2#email.com",
"password" : "test",
"role" : "admin",
"isActive" : true,
"createdat" : ISODate("2017-01-21T07:36:37.337+0000"),
"_id" : ObjectId("58830f85d92f1808e0984306")
},
{
"name" : "reviewName 2_1",
"email" : "reviewName2_1#gmail.com",
"password" : "test",
"role" : "reviewer",
"isActive" : true,
"createdat" : ISODate("2017-01-21T07:55:39.727+0000"),
"_id" : ObjectId("588313fba001380a383e077e")
},
{
"name" : "reviewName 2_2",
"email" : "reviewName2_2#gmail.com",
"password" : "test",
"role" : "reviewer",
"isActive" : true,
"createdat" : ISODate("2017-01-21T07:56:52.963+0000"),
"_id" : ObjectId("588314447bbc230c306804c1")
}
],
"companyname" : "Test Company 2",
"__v" : NumberInt(0)
}
So I would Like to get Following Data
Company Name : Test Company 1,
Reviewer Name : reviewName 1,
Reviewr Email : reviewName1#gmail.com
Company Name : Test Company 2,
Reviewer Name : reviewName 2_1,
Reviewer Email : reviewName2_1#gmail.com
Company Name : Test Company 2,
Reviewer Name : reviewName 2_2,
Reviewer Email : reviewName2_2#gmail.com
There will be lot's of companies, so I don't want to go through with loop and use require information in array. because there will be thousands of company and each company have hundreds of reviewer and admin. So If we go through loop then it will be time consuming. I want to get this data only from collection. So I am looking for the query or condition which gives me only require information.
Can someone help me to get these data-only.
You need to use MongoDB aggregation framework for getting the data according to your requirement.
This query will return data in the desired form.
db.collection.aggregate([
{
"$unwind": "$users"
},
{
"$match": {
"users.role":"reviewer"
}
},
{
"$project": {
"_id":0,
"Company Name" : "$companyname",
"Reviewer Name" : "$users.name",
"Reviewer Email" : "$users.email"
}
}
])

How to generate mongodb object id for a sub-document on insert

Inserting a document that also has sub-documents. I am doing this through cli. How do I make mongodb generate a object id for the Alerts sub-document record? I want something like the following, but this does not work from cli.
db.user.insert(
{
"Email" : "andy+5#domain.com",
"Domain" : "other",
"Type" : "local",
"FName" : "Andy",
"Alerts" : [
{
"_id" : new ObjectId(),
"Keyword" : "sales",
"Frequency" : {
"Type" : "daily"
},
"IsActive" : true
},
{
"_id" : new ObjectId(),
"Keyword" : "customer service",
"Frequency" : {
"Type" : "daily"
},
"IsActive" : true
}
]
}
)
You can run that exact script on the console on robomongo, it would execute just fine. Don't do it on add or edit dialog.

Two MongoDB queries same result, what is the difference?

I'm playing around with mongoDB and I can't figure out what is the difference between my two queries.
I use following collection:
{
"_id" : ObjectId("520b79869971eb1a0fdd0ad4"),
"created" : 1376483718636,
"updated" : 1376483718636,
"firstName" : "Jakob",
"lastName" : "D",
"email" : "jakob.d#test.com",
"emailValidated" : false,
"phoneNumber" : "",
"lastLogin" : 1376483718624,
"linkedProviders" : [
{
"userId" : "1XXXXXXXX6",
"providerId" : "facebook",
"password" : "",
"salt" : "",
"authMethod" : "oauth2",
"avatarUrl" : ""
}
],
"userRoles" : [
"ADMIN"
]
},
{
"_id" : ObjectId("520b7dd09971ebcd35dd0ad6"),
"created" : 1376484816666,
"updated" : 1376484816666,
"firstName" : "Jakob",
"lastName" : "D",
"email" : "jakob.d#test.com",
"emailValidated" : false,
"phoneNumber" : "",
"lastLogin" : 1376484816666,
"linkedProviders" : [
{
"userId" : "jakob.d#test.com",
"providerId" : "userpass",
"password" : "7e4aff9e0d90db2318ffcc689c11b66d",
"salt" : "N1GgNvy3NnS0i5GFDyglQZ9s4CeFNndn",
"authMethod" : "userPassword",
"avatarUrl" : ""
}
],
"userRoles" : [
"ADMIN"
]
}
The two queries that gives me the correct and same result(the one with objectId 520b79869971eb1a0fdd0ad4) are:
db.users.find({"linkedProviders.userId":"1XXXXXXXX6","linkedProviders.providerId":"facebook"})
db.users.find({"linkedProviders": {"$elemMatch": {"userId":"1XXXXXXXX6" },"$elemMatch": {"providerId":"facebook" }}})
So what is the difference between these two?
The difference is that $elemMatch finds items for one single array element.
This solution:
db.users.find({
"linkedProviders.userId": "1XXXXXXXX6",
"linkedProviders.providerId": "facebook"
})
Finds any user that has that userId and that providerId, but possibly in different items in linkedProviders, e.g., if linkedProviders[0].userId matches the first and linkedProviders[1].providerId matches the second part of the query, the full document (i.e., the user) will match that query.
On the other hand,
db.users.find({
"linkedProviders": {
"$elemMatch": {
"userId": "1XXXXXXXX6",
"providerId": "facebook"
}
}
})
will match only if the index values (0 and 1 in the previous example) are the same in the document, i.e., only if one array element matches both.
When there's only one key-value mapping in the $elemMatch, it should do the same as the query with the key-value mapping applied directly.
More information:
http://docs.mongodb.org/manual/reference/operator/elemMatch/#op._S_elemMatch