I have 2 facet on User collection, which are concatenated to create a new array. For each document, i have reference ids to address collection. I need to get the detail about the address. Can it be done on single query using lookup on existing facets together.
Any help is appreciated.
User collection: [
{ "id" : "123456", "name" : "foo", "addressIds" :
[ObjectId(234567)] }, "id" : "345678", "name" : "bar",
"addressIds" : [ObjectId(678565), ObjectId(567456)]
}]
Address collection: [
{ "_id":"234567", "district" : "district1", "pincode" : "568923", },
{ "_id":"678565", "district" : "district2",
"pincode" : "568924", }, { "_id":"567456", "district" :
"district3", "pincode" : "568925", }]
Related
I have employee json as below in db, I want to create a map of "addressId"(key) and "city"(value) and return the result.
{
"_id" :1,
"_class" : "com.entity.Employee",
"clientId" : 1,
"addresses" : [
{
"addressId" : 1,
"street" : "ghi",
"city" : "Hyderabad"
},
{
"addressId" : 2,
"street" : "abc",
"city" : "Bangalore"
},
{
"addressId" : 3,
"street" : "def",
"city" : "Chennai"
}
]
}
Please suggest me which operator can I use and whether this can be achieved using $project.
Yes you have to use projection with unwind and forEach to make key value pair
try below mongo query
db.collection_name.aggregate([{"$unwind":"$addresses"},{"$project": {"addressId": "$addresses.addressId", "city":"$addresses.city", "_class":"$_class","clientId":"$clientId"} }]).forEach(function(ojb){ojb[ojb.addressId]=ojb.city; printjson(ojb);});
I have a collection like the one below
{
"_id" : ObjectId("573eb77bf3465096ddb1e873"),
"id" : 1,
"name" : "siva",
"email" : "sivateja#gmail.com",
"address" : [
{ "street" : "balajinager", "district" : "nellore", "state" : "A.p" },
[ { "street" : "balajinager", "district" : "nellore", "state" : "A.p" } ]
]
}
I want to filter the records based on the city, which is inside the address array, how can we do that in mongo db?
district also fine?
{address:{$elemMatch:{district:"nellore"}}}
see https://docs.mongodb.com/manual/reference/operator/query/elemMatch/
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.
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
I am using MongoDB and trying to remove array elements (themselves embedded documents) from documents in a DB matching a criteria. FOr this I am trying to use the $pull operator in the update command. But I am unable to make this work in some cases (See description below). What am I missing?
Thanks in advance.
-Sachin
> use test
switched to db test
//First, insert a record with an array of addresses, with array elements being embedded objects with exactly 1 element (email)
> db.users.insert({
name: 'smith',
addresses:[{email:'a#b'},{email:'c#d'}]
});... ... ...
//Result of the insertion
> db.users.find()
{ "_id" : ObjectId("50226b46545b516cdbadbcd9"), "name" : "smith", "addresses" : [ { "email" : "a#b" }, { "email" : "c#d" } ] }
//From records with name= Smith, try to $pull any array elements with email a#b
> db.users.update({name:'smith'}, {$pull:{addresses:{email:'a#b'}}});>
//After successful $pull
> db.users.find()
{ "_id" : ObjectId("50226b46545b516cdbadbcd9"), "name" : "smith", "addresses" : [ { "email" : "c#d" } ] }
//Now insert a record with an array of addresses, with array elements being embedded objects with exactly 2 elements (email, phone)
> db.users.insert({
name: 'smith',
addresses:[{email:'a#b', phone: '12345'},{email:'c#d',phone :'54321'}]
});... ... ...
//Result of the insertion
> db.users.find()
{ "_id" : ObjectId("50226b46545b516cdbadbcd9"), "name" : "smith", "addresses" : [ { "email" : "c#d" } ] }
{ "_id" : ObjectId("50226bfc545b516cdbadbcda"), "name" : "smith", "addresses" : [
{
"email" : "a#b",
"phone" : "12345"
},
{
"email" : "c#d",
"phone" : "54321"
}
] }
//From records with name= Smith, again try to $pull any array elements with email a#b
> db.users.update({name:'smith'}, {$pull:{addresses:{email:'a#b'}}})
// - Unsuccessful $pull (Why? How to fix this)
> db.users.find()
{ "_id" : ObjectId("50226b46545b516cdbadbcd9"), "name" : "smith", "addresses" : [ { "email" : "c#d" } ] }
{ "_id" : ObjectId("50226bfc545b516cdbadbcda"), "name" : "smith", "addresses" : [
{
"email" : "a#b",
"phone" : "12345"
},
{
"email" : "c#d",
"phone" : "54321"
}
] }
//Meanwhile, the single element pull still works as before -
> db.users.update({name:'smith'}, {$pull:{addresses:{email:'c#d'}}})
> db.users.find()
{ "_id" : ObjectId("50226b46545b516cdbadbcd9"), "name" : "smith", "addresses" : [ ] }
{ "_id" : ObjectId("50226bfc545b516cdbadbcda"), "name" : "smith", "addresses" : [
{
"email" : "a#b",
"phone" : "12345"
},
{
"email" : "c#d",
"phone" : "54321"
}
] }
>
Thanks for the resposen, although that didn't work. Here is the transcript of the Mongo shell.
> db.users.find()
{ "_id" : ObjectId("50226b46545b516cdbadbcd9"), "name" : "smith", "addresses" : [ ] }
{ "_id" : ObjectId("50226bfc545b516cdbadbcda"), "name" : "smith", "addresses" : [
{
"email" : "a#b",
"phone" : "12345"
},
{
"email" : "c#d",
"phone" : "54321"
}
] }
> db.users.update({name:'smith'}, {$pull:{"addresses.email": 'a#b'}})
Modifier spec implies existence of an encapsulating object with a name that already represents a non-object, or is referenced in another $set clause
> db.users.find()
{ "_id" : ObjectId("50226b46545b516cdbadbcd9"), "name" : "smith", "addresses" : [ ] }
{ "_id" : ObjectId("50226bfc545b516cdbadbcda"), "name" : "smith", "addresses" : [
{
"email" : "a#b",
"phone" : "12345"
},
{
"email" : "c#d",
"phone" : "54321"
}
] }
>
...so basically the dot notation didnt work out.
Ok, so I found the answer.
First thing, I was using MongoDB 1.2.2, and this version didnt support the update $pull operation as described above.
Next, I upgraded to MongoDB 2.06 (latest stable). Then when I use the old database created in 1.2.2, the same result.
Next, I created a new DB in 2.06 and then tried the suggestion by #sergio-tulentsev, i.e.
db.users.update({name:'smith'}, {$pull:{"addresses.email": 'a#b'}})
Unfortunately, this didnt work either.
Last, I tried the initial command I had not been able to execute
db.users.update({name:'smith'}, {$pull:{addresses:{email:'a#b'}}})
And it worked!!!
So takeaway:
1. Update MongoDB server
2. Old version of Database file wont work, only works with new database file. Now I need to somehow migrate my data to the newer version.
UPDATE:...this migration was as simple as issuing the mongod --upgrade command.