Facets and lookup in Mongodb C# - mongodb

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

MongoDB : Push data to a map

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);});

How to fliter based on the embeded collection field in mongo db

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/

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

How do I $pull array element by field value (when elements are objects)

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.