JasperReports MongoDB Query How to access subdocument? - mongodb

We have a document stored in MongoDB which looks like this:
{
"id" : 1,
"name" : "demo-name",
"lastModified" : ISODate("2015-01-07T07:19:35Z"),
"snapshot" : {
"rows" : [
{
"quantity" : 100,
"rate" : 32,
"description" : "22MM SHROUDED PBA RED",
"productCatlgNo" : "3MA40 00 AA0"
},
{
"quantity" : 125,
"rate" : 32,
"description" : "22MM SHROUDED PBA BLACK",
"productCatlgNo" : "3MA40 01 AA0"
}
]
}
}
I am trying to access this document and read only the data stored in the snapshot.rows in JasperStudio report designer using the following query:
{
'collectionName' : 'views.abcdefghi',
'findQuery' : {
'name': 'demo-name'
},
'findFields':{
'snapshot.rows': 1
}
}
But the output contains only snapshot.rows whereas I want the inner details of the documents present in the rows.
How should I go about it?

This could be your answer (based on this link)
}
runCommand:
{
aggregate : 'views.abcdefghi',
pipeline :
[
{$match : {"name" : "demo-name"}},
{$project : {"rows" : "$snapshot.rows" }},
]
}
}
after running the command (on sample document) db.test.aggregate([ {$project : {"rows" : "$snapshot.rows"}} ]).result in mongo shell I had this result (just ids and rows):
{
"0" : {
"_id" : ObjectId("54b9017ec283f0c25c9cbf5e"),
"rows" : [
{
"quantity" : 100,
"rate" : 32,
"description" : "22MM SHROUDED PBA RED",
"productCatlgNo" : "3MA40 00 AA0"
},
{
"quantity" : 125,
"rate" : 32,
"description" : "22MM SHROUDED PBA BLACK",
"productCatlgNo" : "3MA40 01 AA0"
}
]
}
}

Related

How to model this data on MongoDB

I have this data:
{
"_id" : ObjectId("5a75baada0f20bd4e612d480"),
"Number" : 400,
"Page" : 24,
"DC" : "NE",
}
{
"_id" : ObjectId("5a75baada0f20bd4e612d489"),
"Number" : 300,
"Page" : 14,
"DC" : "100",
}
And i want to model this data so it stays like this:
{Crs:{[
{Cr: {
"_id" : ObjectId("5a75baada0f20bd4e612d480"),
"Number" : 400,
"Page" : 24,
"DC" : "NE",
}},
{Cr: {
"_id" : ObjectId("5a75baada0f20bd4e612d489"),
"Number" : 300,
"Page" : 14,
"DC" : "100",
}},
]}}
I read something about Model One-to-Many Relationships with Embedded Documents but i really dont know how it works.
https://docs.mongodb.com/manual/core/data-model-design/
use aggregation
> db.crs.aggregate(
[
{$group : {_id : null, crs : {$push : {cr : "$$ROOT"}}}},
{$project : {_id : 0}}
]
).pretty()
you can also write the result data to another collection using $out
add below as last stage in aggregate pipeline
{$out : "crs"} // create collection crs
output
> db.crs.aggregate([{$group : {_id : null, crs : {$push : {cr : "$$ROOT"}}}}, {$project : {_id : 0}}]).pretty()
{
"crs" : [
{
"cr" : {
"_id" : ObjectId("5a75baada0f20bd4e612d480"),
"Number" : 400,
"Page" : 24,
"DC" : "NE"
}
},
{
"cr" : {
"_id" : ObjectId("5a75baada0f20bd4e612d489"),
"Number" : 300,
"Page" : 14,
"DC" : "100"
}
}
]
}
>
I think the documentation here should be of some help: https://docs.mongodb.com/manual/reference/operator/update/positional/#update-documents-in-an-array
And in your case it would be something similar to this:
db.nameOfCollection.updateOne(
{ _id: ObjectId('idhere'), "Crs.Cr.Number": 400 },
{ $set: { "Crs.$.Cr.DC" : "SomethingNew" } }
)
One thing here, I'm not sure you're data structure seems correct as you have an array inside an object...why not just an array, i.e.
Crs: [{...}, {...}]

Aggregate based on Array value

I have collection schema like :
{
"_id" : ObjectId("582ee289618a504e5c830e03"),
"updatedAt" : ISODate("2016-11-24T05:01:59.470Z"),
"createdAt" : ISODate("2016-11-18T11:14:17.912Z"),
"requestId" : "IER5R2H",
"pickupDetails" : {
"_id" : ObjectId("58367447b0a1ada74ad7af7e"),
"itemsCount" : 1,
"pickupItems" : [
{
"name" : "Newspaper",
"quantity" : 15,
"unit" : "kg",
"unitPrice" : 9,
"amount" : 135,
"_id" : ObjectId("58367447b0a1ada74ad7af7f")
}
]
}}
{
"_id" : ObjectId("58fff31a618a504e5c831191"),
"updatedAt" : ISODate("2016-11-21T13:37:51.267Z"),
"createdAt" : ISODate("2016-11-19T06:37:14.857Z"),
"requestId" : "M7OZY9O",
"pickupDetails" : {
"_id" : ObjectId("5832f8afb8ec77fa3c518f97"),
"itemsCount" : 2,
"pickupItems" : [
{
"name" : "Newspaper",
"quantity" : 18,
"unit" : "kg",
"unitPrice" : 11,
"amount" : 198,
"_id" : ObjectId("5832f8afb8ec77fa3c518f98")
},
{
"name" : "Plastic",
"quantity" : 4,
"unit" : "kg",
"unitPrice" : 11,
"amount" : 44,
"_id" : ObjectId("584a853e46c71be3585bfb5a")
}
]
}}
I need to add the quantity based on the name of pickupItems, like "Newspaper" etc. Suppose quantity of Newspaper for a particular day.
As per the below data, result should be like, {"Newspaper":33}, for a particular date.
try this :
db.collection.aggregate([
{
$unwind:"$pickupDetails.pickupItems"
},
{
$group:{
_id:"$pickupDetails.pickupItems.name",
quantity:{
$sum:"$pickupDetails.pickupItems.quantity"
}
}
}
])
output:
{ "_id" : "Plastic", "quantity" : 4 }
{ "_id" : "Newspaper", "quantity" : 33 }
you can add a $match stage at the begining of the pipeline to get results for a particular day

Float number overflows when export MongDB collection to JSON via mongoexport

I'm new to MongoDB. I've inserted a float number into a collection. However, when I export that collection via mongoexport, the float number changes.
This is what in the database:
{ "_id" : ObjectId("56653e23a6b56616ba417bcd"), "id" : "601318", "name" : "中国平安", "buy" : [ { "time" : ISODate("2015-06-15T01:30:00Z"), "price" : 86.9, "quantity" : 1000, "value" : 87074.4 } ], "sell" : [ { "time" : ISODate("2015-07-07T01:30:00Z"), "price" : 80.88, "quantity" : 1000, "value" : 80636.76 } ] }
This is when it's exported to json:
{ "_id" : { "$oid" : "56653e23a6b56616ba417bcd" }, "id" : "601318", "name" : "中国平安", "buy" : [ { "time" : { "$date" : "2015-06-15T09:30:00.000+0800" }, "price" : 86.90000000000001, "quantity" : 1000, "value" : 87074.39999999999 } ], "sell" : [ { "time" : { "$date" : "2015-07-07T09:30:00.000+0800" }, "price" : 80.88, "quantity" : 1000, "value" : 80636.75999999999 } ] }
How to avoid this overflow?
Store the value as an integer: 8063676 (cents or whatever).
See this question.

mongodb Embedded document search on parent and child field

I have a nested embedded document CompanyProduct below is structure
{
"_id" : ObjectId("53d213c5ddbb1912343a8ca3"),
"CompanyID" : 90449,
"Name" : Company1,
"CompanyDepartment" : [
{
"_id" : ObjectId("53d213c5ddbb1912343a8ca4")
"DepartmentID" : 287,
"DepartmentName" : "Stores",
"DepartmentInventory" : [
{
"_id" : ObjectId("53b7b92eecdd765430d763bd"),
"ProductID" : 1,
"ProductName" : "abc",
"Quantity" : 100
},
{
"_id" : ObjectId("53b7b92eecdd765430d763bd"),
"ProductID" : 2,
"ProductName" : "xyz",
"Quantity" : 1
}
],
}
],
}
There can be N no of companies and each company can have N number of departments and each department can have N number of products.
I want to do a search to find out a particular product quantity under a particular company
I tried below query but it does not work. It returns all the products for the specific company, the less than 20 condition doesn't work.
db.CompanyProduct.find({$and : [{"CompanyDepartment.DepartmentInventory.Quantity":{$lt :20}},{"CompanyID":90449}]})
How should the query be?
You are searching from companyProduct's sub documents. So it will return you companyProduct whole document, it is NoSQL database , some how we do not need to normalize the collection , but your case it has to be normalize , like if you want to EDIT/DELETE any sub document and if there are thousand or millions of sub document then what will you do ... You need to make other collection with the name on CompanyDepartment and companyProduct collection should be
productCompany
{
"_id" : ObjectId("53d213c5ddbb1912343a8ca3"),
"CompanyID" : 90449,
"Name" : Company1,
"CompanyDepartment" : ['53d213c5ddbb1912343a8ca4'],
}
and other collection companyDepartment
{
"_id" : ObjectId("53d213c5ddbb1912343a8ca4")
"DepartmentID" : 287,
"DepartmentName" : "Stores",
"DepartmentInventory" : [
{
"_id" : ObjectId("53b7b92eecdd765430d763bd"),
"ProductID" : 1,
"ProductName" : "abc",
"Quantity" : 100
},
{
"_id" : ObjectId("53b7b92eecdd765430d763bd"),
"ProductID" : 2,
"ProductName" : "xyz",
"Quantity" : 1
}
],
}
after this you got array of companyDeparment' ID and only push and pull query will be used on productCompany
A Solution can be
db.YourCollection.aggregate([
{
$project:{
"CompanyDepartment.DepartmentInventory":1,
"CompanyID" : 1
}
},{
$unwind: "$CompanyDepartment"
},{
$unwind: "$CompanyDepartment.DepartmentInventory"
},{
$match:{$and : [{"CompanyDepartment.DepartmentInventory.Quantity":{$lt :20}},{"CompanyID":90449}]}
}
])
the result is
{
"result" : [
{
"_id" : ObjectId("53d213c5ddbb1912343a8ca3"),
"CompanyID" : 90449,
"CompanyDepartment" : {
"DepartmentInventory" : {
"_id" : ObjectId("53b7b92eecdd765430d763bd"),
"ProductID" : 2,
"ProductName" : "xyz",
"Quantity" : 1
}
}
}
],
"ok" : 1
}

using aggregation in mongodb

I have following records in mongodatabase.
> db.student.find()
{ "_id" : ObjectId("52ca76140e468ba197e50c23"), "name" : "pratik", "subject" : "maths", "marks" : 68 }
{ "_id" : ObjectId("52ca762b0e468ba197e50c24"), "name" : "pratik", "subject" : "biology", "marks" : 96 }
{ "_id" : ObjectId("52ca77a90e468ba197e50c25"), "name" : "pratik", "subject" : "maths", "marks" : 40 }
From this record I want to know the total marks obtained for just maths subject.
Here is what I have tried,but I don't know what is going wrong in the following query.
db.student.aggregate(
{$match: { 'subject': "maths"}},
{ $group : { _id :{ name:"$name",subject:"$subject",marks:"$marks" },
total: { $sum : "$marks"}}
})
{
"result" : [
{
"_id" : {
"name" : "pratik",
"subject" : "maths",
"marks" : 40
},
"total" : 40
},
{
"_id" : {
"name" : "pratik",
"subject" : "maths",
"marks" : 68
},
"total" : 68
}
],
"ok" : 1
}
Could you please let me know what has went wrong in the above query along with the correct answers.
Also suggest me the appropriate guide to use the aggregation module so that I can use it efficiently.I am beginner to aggregation module of mongo database.
Thanks in Advance.
The problem is the marks field in the group within the _id. It will group upon mark scores then which is useless to you, instead you want:
db.student.aggregate(
{$match: { 'subject': "maths"}},
{$group : {
_id :{ name:"$name", subject:"$subject" },
total: { $sum : "$marks"}
}}
);