need to find a way to get data inside subdocument in mongo - mongodb

I need a way to find inside nested array documents.
I want to find value matching inside street_1.
this is my query:
db.phonebook.find({'address.home.street_1' : 'street 1 result'});
and my document:
{
"_id" : ObjectId("53788c0c74d3ead0098b4568"),
"first_name" : "jarod",
"last_name" : "petters",
"company" : "nostromos",
"phone_numbers" : [
{
"cell" : "0752203337"
},
{
"home" : "0850819201"
},
{
"home" : "0499955550"
}
],
"website" : "http://www.mywebsite.com",
"email" : [
{
"home" : "email.first.com"
},
{
"office" : "email.second.com"
}
],
"address" : [
{
"home" : {
"stree_1" : "street 1 result",
"stree_2" : "",
"postal_code" : "66502",
"city" : "my littre city",
"country" : "usa"
}
}
],
"nationality" : "mars",
"date_of_birth" : "1978-01-01"
}

Your query is the good one. But your document is not good, you have done a mistake in your document, you write stree_1 instead of street_1. If your document is right, change your query to :
db.phonebook.find({'address.home.stree_1' : 'street 1 result'});

Related

Need find query for dynamic multiple nested collections in mongodb

I need to find collections based nested on values.But my collection having dynamic values . See below code. In which image name keys are dynamic ( _DSC9691.jpg , _DSC9514.JPG ) and " key1 " is dynamic items. Now I need to find collection based on component, material, Subtype
{
"_id" : ObjectId("5ce2df8498f10b276cb466c4"),
"num" : "1",
"lat" : "39.941436099965",
"lon" : "-86.0691700063581",
"images" : {
"_DSC9691.jpg" : {
"key1" : {
"component" : "Sleeve",
"condition" : "",
"sub_type" : {
"Auto Sleeve" : true
},
"material" : "",
"misc" : ""
}
}
}}
{
"_id" : ObjectId("5ce2df8498f10b276cb466c7"),
"num" : "4",
"lat" : "39.9413828961847",
"lon" : "-86.0715084495015",
"images" : {
"_DSC9554.JPG" : {
},
"_DSC9514.JPG" : {
},
"_DSC9622.JPG" : {
}
}}
#Nagendran you won't be able to perform those operations because the nested document that you want to watch isn't named properly. I suggest you to rename that field using a common name and try to use the code bellow. Also remember to not use blank spaces on field names like "Auto Sleeve".
Object:
{
"_id" : ObjectId("5ce2df8498f10b276cb466c7"),
"num" : "4",
"lat" : "39.9413828961847",
"lon" : "-86.0715084495015",
"images" : [
{
"name" : "some name",
"key":
{
"component" : "Sleeve",
"condition" : "",
"sub_type" : {
"Auto_Sleeve" : true
},
"material" : "",
"misc" : ""
},
},
{
"name" : "some name 2",
"key":
{
"component" : "Sleeve 2",
"condition" : "",
"sub_type" : {
"Auto_Sleeve" : true
},
"material" : "",
"misc" : ""
},
},
]
}
Query:
db.collection.find({
"images.key.sub_type.Auto_Sleeve": true
})
If you want you can use aggregation framework to filter inside the "images" nested document.
To get a litle bit more information you can access:
https://docs.mongodb.com/manual/aggregation/
https://docs.mongodb.com/manual/tutorial/query-documents/
https://www.mongodb.com/blog/post/6-rules-of-thumb-for-mongodb-schema-design-part-1
https://university.mongodb.com/

calculated field in MongoDB

My document is as below.
{
"name" : "MadhuA"+i,
"lastname" : "MohanB"+i,
"created" : new Date(),
"Address" : [
{
"Home Address" : "St:123, Abcd road, cityA, stateB, Pin code123",
"Work Address" : "St:134, xyz road, cityV, stateX, pin code456",
"Billing Address" : "St:156, pppp road, cityZ, stateNm ,Pincode154"
}
],
"tariff" : [
{
"Service" : "Broadband",
"Recurring" : "Monthly",
"Fee" : 100
}
],
"charges" : [ {
"charge_details" : [
{
"start_date" : "01-JAN-2016",
"end_date" : "01-FEB-2016",
"charge_amount" : Math.floor(Math.random()*400),
"Status" : "Outstanding",
"Service" : "Broadband",
"charge_type" : "monthly"
},
{
"start_date" : "01-JAN-2016",
"end_date" : "01-FEB-2016",
"charge_amount" : Math.floor(Math.random()*400),
"Status" : "Outstanding",
"Service" : "VoIP",
"charge_type" : "monthly"
}
] }
]
}
I want the Total amount to be populated with all the charge_amounts in the charges field. Whenever there is a charge_amount added to the document, the total_amount should be changed accordingly.
Please let me know if we have such functionality.
<3
If I understand correctly you are trying to add a property totalAmount such that:
Contain the list of charge_amount values
Changes dynamically when the document changes
If this is the case the best solution is to use Mongo 3.4 with views, writing something like:
db.createView("totalAmount", "collection", [
{
$addFields: {
totalAmount: "$charges.charge_details.charge_amount"
}
},
{
$addFields: {
totalAmount: { $arrayElemAt: ["$totalAmount",0] }
}
},
])
Here I am assuming that your collection is called "collection"
Now, you can query the new view and you will see the totalAmount:
db.totalAmount.find().pretty
shows:
{
"_id" : ObjectId("5856c41fbd0535e2fb8fb2ff"),
"name" : "MadhuA",
"lastname" : "MohanB",
"created" : ISODate("2016-12-18T17:15:11.797Z"),
"Address" : [
{
"Home Address" : "St:123, Abcd road, cityA, stateB, Pin code123",
"Work Address" : "St:134, xyz road, cityV, stateX, pin code456",
"Billing Address" : "St:156, pppp road, cityZ, stateNm ,Pincode154"
}
],
"tariff" : [
{
"Service" : "Broadband",
"Recurring" : "Monthly",
"Fee" : 100
}
],
"charges" : [
{
"charge_details" : [
{
"start_date" : "01-JAN-2016",
"end_date" : "01-FEB-2016",
"charge_amount" : 37,
"Status" : "Outstanding",
"Service" : "Broadband",
"charge_type" : "monthly"
},
{
"start_date" : "01-JAN-2016",
"end_date" : "01-FEB-2016",
"charge_amount" : 398,
"Status" : "Outstanding",
"Service" : "VoIP",
"charge_type" : "monthly"
}
]
}
],
"totalAmount" : [
37,
398
]
}
Moreover, if you add new documents to "collection" or modify any document the view (in particular totalAmount) will change accordingly.
Got this error:
> db.totalAmount.find({"name" : "MadhuA4097899"}).pretty()
Error: error: {
"ok" : 0,
"errmsg" : "$arrayElemAt's first argument must be an array, but is int",
"code" : 28689,
"codeName" : "Location28689"
}

MongoDB find substructure

I have a mongodb with a table named Patient. When I display the content with MongoVUE I see my Patients in this format:
/* 0 */
{
"_id" : ObjectId("547c4aa9dbe9665042dddf76"),
"Patient" : {
"Maidenname" : { },
"Phone" : {
"Type" : { },
"Number" : { }
},
"Citizenship" : { },
"SSN" : 1234567,
"Profession" : { },
"systemUID" : { },
"lid" : 111,
"system" : "abc",
"Address" : {
"Street" : { },
"State" : { },
"Zip" : { },
"Country" : { },
"City" : { }
},
"Lastname" : "asdf",
"Firstname" : "Test",
"Birthdate" : 19000101,
"Identifier" : {
"id" : 123,
"system" : "abc",
"UID" : { }
}
}
}
I would like to make a find on the field Firstname with value Test, this is my query:
db.Patient.find({Firstname:"Test"})
But it returns 0 rows.
I also tried this one:
db.Patient.find({Patient : {Firstname:"Test"}})
Also 0 rows returned.
When I do a find like this:
db.Patient.find()
I get all data. (also the one with "Firstname" : "Test")
Can anyone help me with that find query?
Should try this it work well
db.patiens.find({"Patient.Firstname":"Test"})
Since Firstname is in Patient object, it is its property you need to select is as
db.Patient.find({"Patient.Firstname":"Test"})

index search returns all subdocuments

I would like to only return my embedded documents titled 'Listings', based on the text search query. Where may I be going wrong? Creation of the index?
Here is my index:
db.Collection.ensureIndex({"Listings.Title": "text", "Listings.Description" : "text"}, {name: "Search"})
This returns the whole object, only want listings
db.AspNetUsers.runCommand("text", { search: "lawn" })
this returns just listings, but all the listings are included. Not the listings based on the search criteria e.g. 'lawn'
db.AspNetUsers.runCommand("text", { search: "lawn", project: {Listings:1}})
here is my object
{
"_id" : ,
"UserName" : "",
"PasswordHash" : "",
"SecurityStamp" : "",
"Roles" : [],
"Claims" : [],
"Logins" : [],
"ProfileData" : {
"BirthDate" : new Date("3/8/1974 00:00:00"),
"FirstName" : "",
"LastName" : "",
"MiddleName" : "",
"Address" : "",
"Address1" : ,
"City" : "",
"State" : "",
"PostalCode" : "",
"CellPhone" : "",
"HomePhone" : "",
"Location" : {
"type" : "Point",
"coordinates" : [, ]
}
},
"Email" : "",
"ConfirmationToken" : "Confirmed",
"IsConfirmed" : true,
"Listings" : [{
"_id" : ObjectId("5331ac28a5eabf2854085df5"),
"UserId" : ObjectId("5329b43fa5eabf0548490c27"),
"Title" : "Lawn Chairs",
"Description" : "lawn chairs",
"Pictures" : ["5331ac28a5eabf2854085df6", "5331ac28a5eabf2854085df7", "5331ac28a5eabf2854085df8"],
"Category" : {
"_id" : ObjectId("53273ce37dd6c71e1859ab77"),
"Title" : "Leisure"
}
}, {
"_id" : ObjectId("5331ac50a5eabf2854085df9"),
"UserId" : ObjectId("5329b43fa5eabf0548490c27"),
"Title" : "Lawn Ornaments",
"Description" : "lawn ornaments troll frog gnome",
"Pictures" : ["5331ac50a5eabf2854085dfa", "5331ac50a5eabf2854085dfb", "5331ac51a5eabf2854085dfc"],
"Category" : {
"_id" : ObjectId("53273cd57dd6c71e1859ab76"),
"Title" : "Home"
}
}, {
"_id" : ObjectId("5331ac71a5eabf2854085dfd"),
"UserId" : ObjectId("5329b43fa5eabf0548490c27"),
"Title" : "Cell Phone",
"Description" : "Samsung Galaxy S4",
"Pictures" : ["5331ac71a5eabf2854085dfe", "5331ac71a5eabf2854085dff", "5331ac72a5eabf2854085e00"],
"Category" : {
"_id" : ObjectId("53273cd57dd6c71e1859ab76"),
"Title" : "Home"
}
}]
}
You can get just the fields you want using a project parameter. For getting just the Listings element, you could try:
db.AspNetUsers.runCommand("text", {search:"lawn", project:{_id:0, Listings:1}})
EDIT:
The text command will return all documents that contain the search term. You'll get the entire document. If you further want to filter an array inside of the document, you can use the $elemMatch projection operator, in combination with $regex. For example:
db.AspNetUsers.runCommand("text", {
search: "lawn",
project: {_id:0, Listings:{$elemMatch:{ "Title": /lawn/i }}}
})

How to get exact document result from key value type of embedded documents

Let say I have this kind of document structured, the attributes field will be the embedded document
and I've already indexed the attributes.key and attributes.value
1-------------------------------------------------------------------------------------
{
"_id" : ObjectId( "5191d8e5d00560402e000001" ),
"attributes" : [
{ "key" : "pobox","value" : "QaKUWo" },
{ "key" : "city", "value" : "CBDRip" },
{ "key" : "address","value" : "zmycAa" } ],
"email" : "FWAUdl_2#email.com",
"firstname" : "FWAUdl_2"
}
2-------------------------------------------------------------------------------------
{
"_id" : ObjectId( "5191d8e7d00560402e000055" ),
"attributes" : [
{ "key" : "pobox", "value" : "sNFriy" },
{ "key" : "city", "value" : "JPdVrI" },
{ "key" : "address", "value" : "phOluW" } ],
"email" : "hqYNWH_86#email.com",
"firstname" : "hqYNWH_86"
}
My problem is how to get exact document when querying based only on the attributes field,
db.app.find({ attributes.key:address , attributes.value:/.*uw.*/i })
The query result is not as I expected, it should result only the 2nd document only without the 1st document.
I know that I put regex on the attributes.value, I was expecting that it only check for attributes.key that have address value.
And what if I want to filter another key, such like,
db.app.find({ attributes.key:address , attributes.value:/.*uw.*/i , attributes.key:city , attributes.value:/.*ri.*/i })
Any opinion will be helpful guys.
Thx.
I guess you need $elemMatch ( http://docs.mongodb.org/manual/reference/operator/elemMatch/ )
db.test123.find({ attributes : { $elemMatch : { 'key':"address" , 'value':/.*uw.*/i } } }).pretty()
{
"_id" : ObjectId("5191d8e7d00560402e000055"),
"attributes" : [
{
"key" : "pobox",
"value" : "sNFriy"
},
{
"key" : "city",
"value" : "JPdVrI"
},
{
"key" : "address",
"value" : "phOluW"
}
],
"email" : "hqYNWH_86#email.com",
"firstname" : "hqYNWH_86"
}
Just investigated a little and figured out following. The following uses the index mentioned below. You can do a explain() on the find() to check more index usage details
db.testing.getIndexKeys()
[ { "_id" : 1 }, { "attributes.key" : 1, "attributes.value" : 1 } ]
test:Mongo > db.testing.find({$and : [ { attributes : {$elemMatch : {key : 'address', value : /.*uw.*/i }} }, { attributes : {$elemMatch : {key : 'city', value : /.*ri.*/i }} }] }).pretty()
{
"_id" : ObjectId("5191d8e7d00560402e000055"),
"attributes" : [
{
"key" : "pobox",
"value" : "sNFriy"
},
{
"key" : "city",
"value" : "JPdVrI"
},
{
"key" : "address",
"value" : "phOluW"
}
],
"email" : "hqYNWH_86#email.com",
"firstname" : "hqYNWH_86"
}