Mongoid query embedded document and return parent - mongodb

I have this document, each is a tool:
{
"_id" : ObjectId("54da43aea96ddcc40915a457"),
"checked_in" : false,
"barcode" : "PXJ-234234",
"calibrations" : [
{
"_id" : ObjectId("54da46ec546173129d810100"),
"cal_date" : null,
"cal_date_due" : ISODate("2014-08-06T00:00:00.000+0000"),
"time_in" : ISODate("2015-02-10T17:46:20.250+0000"),
"time_out" : ISODate("2015-02-10T17:46:20.250+0000"),
"updated_at" : ISODate("2015-02-10T17:59:08.796+0000"),
"created_at" : ISODate("2015-02-10T17:59:08.796+0000")
},
{
"_id" : ObjectId("5509e815686d610b70010000"),
"cal_date_due" : ISODate("2015-03-18T21:03:17.959+0000"),
"time_in" : ISODate("2015-03-18T21:03:17.959+0000"),
"time_out" : ISODate("2015-03-18T21:03:17.959+0000"),
"cal_date" : ISODate("2015-03-18T21:03:17.959+0000"),
"updated_at" : ISODate("2015-03-18T21:03:17.961+0000"),
"created_at" : ISODate("2015-03-18T21:03:17.961+0000")
},
{
"_id" : ObjectId("5509e837686d610b70020000"),
"cal_date_due" : ISODate("2015-03-18T21:03:51.189+0000"),
"time_in" : ISODate("2015-03-18T21:03:51.189+0000"),
"time_out" : ISODate("2015-03-18T21:03:51.189+0000"),
"cal_date" : ISODate("2015-03-18T21:03:51.189+0000"),
"updated_at" : ISODate("2015-03-18T21:03:51.191+0000"),
"created_at" : ISODate("2015-03-18T21:03:51.191+0000")
}
],
"group" : "Engine",
"location" : "Here or there",
"model" : "ZX101C",
"serial" : NumberInt(15449),
"tool" : "octane analyzer",
"updated_at" : ISODate("2015-09-30T20:43:55.652+0000"),
"description" : "Description...",
}
Tools are calibrated periodically. What I want to do is grab tools that are due this month.
Currently, my query is this:
scope :upcoming, -> { where(:at_ats => false).where('calibrations.0.cal_date_due' => {'$gte' => Time.now-1.day, '$lte' => Time.now+30.days}).order_by(:'calibrations.cal_date_due'.asc) }
However, this query gets the tool by the first calibration object and it needs to be the last. I've tried a myriad of things, but I'm stuck here.
How can I make sure I'm querying the most recent calibration document, not the first (which would be the oldest and therefore not relevant)?

You should look into aggregation framework and $unwind operator.
This link may be of help.
This link may be helpful. It contains an example of use of 'aggregation framework' for get the last element of the array, that is, the most recent in your case.

Related

how to calculate time difference based on 2 fields in mongodb

I am familiar to simple mongodb queries but this one is a bit complex for me. Here, what I am trying to achieve is on the basis of jsonObject.callID and jsonObject.mobile fields I have to calculate time difference of jsonObject.timestamp. For example in below sample documents, jsonObject.callID and mobile will remain same for jsonObject.action start and end. So based on jsonObject.callID and jsonObject.mobile, I have to subtract the jsonObject.timestamp. jsonObject.callId will be same for two interval actions i.e. start and end with their same jsonObject.mobile numbers.
{
"_id" : ObjectId("5df9bc5ee5e7251030535df5"),
"_class" : "com.abc.mongo.docs.IvrMongoLog",
"jsonObject" : {
"mode" : "ivr",
"callID" : "33333",
"callee" : "128",
"action" : "end",
"mobile" : "218924535466",
"timestamp" : "2019-12-18 16:18:12"
}
}
{
"_id" : ObjectId("5df9bc3de5e7251030535df4"),
"_class" : "com.abc.mongo.docs.IvrMongoLog",
"jsonObject" : {
"mode" : "ivr",
"callID" : "33333",
"callee" : "128",
"action" : "start",
"mobile" : "218924535466",
"timestamp" : "2019-12-18 16:12:11"
}
}
So I am trying to achieve a output like below:
{
"callee" : "128",
"mobile" : "218924535466",
"callID" : "33333",
"minutes_of_call" : "6" // difference of "2019-12-18 16:18:12" - "2019-12-18 16:12:11"
}
subsequently I need such results for next documents...
Kindly assist.

CosmosDB Invalid BSON With Update using $ [duplicate]

Embedded Update query works fine in mlab and atlas but not working in Cosmos DB:
My Collection structure:
{
"_id" : ObjectId("5982f3f97729be2cce108785"),
"password" : "$2y$10$F2P9ITmyKNebpoDaQ1ed4OxxMZSKmKFD9ipiU1klqio239c/nJcme",
"nin" : "123",
"login_status" : 1,
"updated_at" : ISODate("2017-05-16T09:09:03.000Z"),
"created_at" : ISODate("2017-05-16T06:08:47.000Z"),
"files" : [
{
"name" : "abc",
"updated_at" : ISODate("2017-05-16T06:08:48.000Z"),
"created_at" : ISODate("2017-05-16T06:08:48.000Z"),
"_id" : ObjectId("5982f3f97729be2cce108784")
}
],
"name" : "demo",
"email" : "email#gmail.com",
"phone" : "1231234",
}
My query is:
db.rail_zones.update(
{'_id': ObjectId("5982f3f97729be2cce108785"),
'files._id' : ObjectId("5982f3f97729be2cce108784")},
{ $set: {'files.$.name' : "Changed"}})
I get this response:
"acknowledged" : true,
"matchedCount" : 0.0,
"modifiedCount" : 0.0
According to your description, I tested this issue on my side and found the Array Update could not work as expected. I assumed that the Array Update feature has not been implemented in the MongoDB Compatibility layer of Azure CosmosDB. Moreover, I found a feedback Positional array update via '$' query support talking about the similar issue.

Mongodb put Documents array as the same level

I have this array of documents, I would like to put "table" on the same level like mastil_antenas and other variables. how Can I do that with aggregate?
I'm trying with the aggregate $project but I can't get the result.
Example of Data
[ {
"mastil_antena" : "1",
"nro_platf" : "1",
"antmarcmast" : "ANDREW",
"antmodelmast" : "HWXXX6516DSA3M",
"retmarcmast" : "Ericsson",
"retmodelmast" : "ATM200-A20",
"distmast" : "1.50",
"altncramast" : "41.30",
"ORIENTMAG" : "73.00",
"incelecmast" : "RET",
"incmecmast" : "1.00",
"Feedertypemast" : "Fibra Optica",
"longjumpmast" : "5.00",
"longfo" : "100",
"calibrecablefuerza" : "10 mm",
"longcablefuerza" : "65.00",
"modelorruantena" : "32B66A",
"tiltmecfoto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114934746000.jpg",
"tiltmecfoto_fh" : "2017-10-18T05:51:22Z",
"az0foto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017115012727000.jpg",
"az0foto_fh" : "2017-10-18T05:55:21Z",
"azneg60foto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017115016199000.jpg",
"azneg60foto_fh" : "2017-10-18T05:55:36Z",
"azpos60foto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017115020147000.jpg",
"azpos60foto_fh" : "2017-10-18T05:55:49Z",
"etiqantenafoto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114920853000.jpg",
"etiqantenafoto_fh" : "2017-10-18T05:56:01Z",
"tiltelectfoto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114914236000.jpg",
"tiltelectfoto_fh" : "2017-10-18T05:56:13Z",
"idcablefoto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114900279000.jpg",
"idcablefoto_fh" : "2017-10-18T05:56:38Z",
"rrutmafoto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114947279000.jpg",
"rrutmafoto_fh" : "2017-10-18T05:56:49Z",
"etiquetarrufoto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114954648000.jpg",
"etiquetarrufoto_fh" : "2017-10-18T05:57:02Z",
"rrutmafoto1" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114959738000.jpg",
"rrutmafoto1_fh" : "2017-10-18T05:57:12Z",
"etiquetarrufoto1" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017115005545000.jpg",
"etiquetarrufoto1_fh" : "2017-10-18T05:57:27Z",
"botontorre4" : "sstelcel3",
"table" : { /* put all varibles one level up*/
"tecmast" : "LTE",
"frecmast" : "2100",
"secmast" : "1",
"untitled440" : "Salir"
},
"comentmast" : "",
"longfeedmast" : "",
"numtmasmast" : "",
"otra_marca_antena" : "",
"otro_modelo_antena" : ""
}]
Starting from MongoDB version 3.4 you could use $addFields to do this.
//replace products with what makes sense in your database
db.getCollection('products').aggregate(
[
{ //1 add the properties from subdocument table to documents
$addFields: {
"documents.tecmast" : "documents.0.table.tecmast",
"documents.frecmast" : "documents.0.table.frecmast",
"documents.secmast" : "documents.0.table.secmast",
"documents.untitled440" : "documents.0.table.untitled440"
}
},
{
//(optional) 2 remove the table property from the documents
$project: {"documents.table" : 0}
}
]
)
Step 1: use $addFields to grab properties from table inside documents.table and put them on documents
Step 2: (optional) remove property "table" from documents.
I hope this helps!!!

How to find something from an array in mongo

{
"_id" : ObjectId("586aac4c8231ee0b98458045"),
"store_code" : NumberInt(10800),
"counter_name" : "R.N.Electric",
"address" : "314 khatipura road",
"locality" : "Khatipura Road (Jhotwara)",
"pincode" : NumberInt(302012),
"town" : "JAIPUR",
"gtm_city" : "JAIPUR",
"sales_office" : "URAJ",
"owner_name" : "Rajeev",
"owner_mobile" : "9828024073",
"division_mapping" : [//this contains only 1 element in every doc
{
"dvcode" : "cfc",
"dc" : "trade",
"beatcode" : "govindpura",
"fos" : {
"_id" : ObjectId("586ab8318231ee0b98458843"),
"loginid" : "9928483483",
"name" : "Arpit Gupta",
"division" : [
"cfc",
"iron"
],
"sales_office" : "URAJ", //office
"gtm_city" : "JAIPUR" //city
},
"beat" : {
"_id" : ObjectId("586d372b39f64316b9c3cbd7"),
"division" : {
"_id" : ObjectId("5869f8b639f6430fe4edee2a"),
"clientdvcode" : NumberInt(40),
"code" : "cfc",
"name" : "Cooking & Fabric Care",
"project_code" : "usha-fos",
"client_code" : "usha",
"agent_code" : "v5global"
},
"beatcode" : "govindpura",
"sales_office" : "URAJ",
"gtm_city" : "JAIPUR",
"active" : true,
"agency_code" : "v5global",
"client_code" : "USHA_FOS",
"proj_code" : "usha-fos",
"fos" : {
"_id" : ObjectId("586ab8318231ee0b98458843"),
"loginid" : "9928483483",
"name" : "Arpit Gupta",
"division" : [
"cfc",
"iron"
],
"sales_office" : "URAJ",
"gtm_city" : "JAIPUR"
}
}
}
],
"distributor_mail" : "sunil.todi#yahoo.in",
"project_code" : "usha-fos",
"client_code" : "usha",
"agent_code" : "v5global",
"distributor_name" : "Sundeep Electrical"
}
I am having only 1 element in division_mapping's array and I want to find those documents whose dc in division_mapping is trade.
I have tried following:
"division_mapping":{$elemMatch:{$eq:{"dc":"trade"}}}})
Dont know what I am doing wrong.
//Maybe I have to unwind the array but is there any other way?
According to MongoDB documentation
The $elemMatch operator matches documents that contain an array
field with at least one element that matches all the specified query
criteria.
According to above mentioned description to retrieve only documents whose dc in division_mapping is trade please try executing below mentioned query
db.collection.find({division_mapping:{$elemMatch:{dc:'trade'}}})

Fix duplicate name situation due to entities created before Orion 0.17.0

Since Orion 0.17.0 attribute type is no longer used as attribute "identification key". However, I have entities created with a pre-0.17.0 version that have attributes with the same name and different types. For example, the following entity, which have "ActivePower" duplicated:
> db.entities.findOne({"_id.type": "Regulator", "_id.id": "OUTSMART.RG_LAS_LLAMAS_01", "_id.servicePath": "/"})
{
"_id" : {
"type" : "Regulator",
"id" : "OUTSMART.RG_LAS_LLAMAS_01",
"servicePath" : "/"
},
"attrs" : [
{
"name" : "TimeInstant",
"value" : "2015-04-27T01:51:36.000000Z",
"type" : "urn:x-ogc:def:trs:IDAS:1.0:ISO8601",
"modDate" : 1430092302
},
{
"name" : "ActivePower",
"value" : "11778",
"type" : "urn:x-ogc:def:phenomenon:Outsmart:1.0:ActivePower",
"modDate" : 1430092302
},
{
"name" : "ReactivePower",
"value" : "8414",
"type" : "urn:x-ogc:def:phenomenon:Outsmart:1.0:ReactivePower",
"modDate" : 1430092302
},
{
"name" : "electricPotential",
"value" : "231",
"type" : "urn:x-ogc:def:phenomenon:IDAS:1.0:electricPotential",
"modDate" : 1430092302
},
{
"name" : "electricCurrent",
"value" : "20890",
"type" : "urn:x-ogc:def:phenomenon:IDAS:1.0:electricCurrent",
"modDate" : 1430092302
},
{
"name" : "Latitud",
"value" : "43.4716987609863",
"type" : "urn:x-ogc:def:phenomenon:IDAS:1.0:latitude",
"modDate" : 1414522843
},
{
"name" : "Longitud",
"value" : "-3.80692005157471",
"type" : "urn:x-ogc:def:phenomenon:IDAS:1.0:longitude",
"modDate" : 1401818472
},
{
"name" : "ActivePower",
"creDate" : 1393420396,
"value" : "11778.2",
"type" : "float",
"modDate" : 1430092302
}
],
"modDate" : 1430092302
}
How can I adapt that entity to work with Orion 0.17.0 and beyond?
The simplest solution is to edit the entity using mongo console, to remove all the "duplicated" attributes with the same name and leave only one. In the example above we have one ActivePower with type urn:x-ogc:def:phenomenon:Outsmart:1.0:ActivePower and other with type float. Let's assume we want to kept the first one.
First of all, stop Orion and take a backup of the database. If something gets wrong while you edit the entity, you could need that backup to go back the initial status and try again.
Next, run mongo console (let's assume that your DB is named "orion") and get the entity to modify using findOne() operation. Let's store it in the doc variable.
# mongo orion
> doc = db.entities.findOne({"_id.type": "Regulator", "_id.id": "OUTSMART.RG_LAS_LLAMAS_01", "_id.servicePath": "/"})
...
Now, identify the position within the attrs array of the attribute to remove, taking into account that the position of the first element in the vector is 0 (and not 1). Looking to the above example, the attribute to remove is the 7-th. Check that printing the attribute:
> doc.attrs[7]
{
"name" : "ActivePower",
"creDate" : 1393420396,
"value" : "11778.2",
"type" : "float",
"modDate" : 1430092302
}
Use splice() function to remove the attribute from doc, using as first parameter the position of the attribute and as second parameter 1. Print the doc value to check that it has been removed:
> doc.attrs.splice(7, 1)
...
> doc
Repeat the above operation as many time as you need to remove all duplicated (in the example case, there is only one duplicated). When you are done, save the new version of the entity in the DB:
> db.entities.save(doc)