Group multi addToSet requests in a single request - mongodb

I have the following document :
{
"recordKey": "FOO",
"channels": [{
"id": "CH1",
"blocks": []
}, {
"id": "CH2",
"blocks": []
}]
}
In my current use case, I'm doing two requests with addToSet operator for adding new blocks for the channel CH1 or CH2 For example for the channel CH1, I'm doing this:
selector =
{
"$and" : [ {
"recordKey" : "FOO"
}, {
"channels.id" : "CH1"
} ]
}
addChunkRequest = "$addToSet" : {
"channels.$.blocks" : {
"$each" : [ {
"startime" : 101000000,
"blockType" : "DATA",
"fileLoc" : "/tmp/f1",
"nsamples" : 1000
}
query1 = db.collection.update(selector, update)
I'm doing the same think for the channel CH2. Now I want to group the two requests in one request. How can I achieve that ?

Well you cannot of course "update multiple array elements in the one operation", because that is just not presently allowed and a restriction of the positional $ operator.
What you "can" do however is use Bulk Operations to issue "both" operations in a "single request" to the server:
var data = [
{
"channel": "CH1",
"blocks": [{
"startime" : 101000000,
"blockType" : "DATA",
"fileLoc" : "/tmp/f1",
"nsamples" : 1000
}]
},
{
"channel": "CH2",
"blocks": [{
"startime" : 202000000,
"blockType" : "DATA",
"fileLoc" : "/tmp/f2",
"nsamples" : 2000
}]
}
]
var ops = data.map(d => ({
"updateOne": {
"filter": { "recordKey": "FOO", "channels.id": d.channel },
"update": {
"$addToSet": { "channels.$.blocks": { "$each": d.blocks } }
}
}
});
db.collection.bulkWrite(ops);
So it's still "two" operations and that cannot be avoided, however it's only "one" request and response from the server, and that actually helps you quite a lot.

Related

I am new to mongoDB need a query to delete the collections

I have two collections.
1.Equipment
db.getCollection("Equipment").find({
$and: [
{ $where: 'this._id.length <= 7' },
{ "model": "A505"}
]})
{
"_id" : "1234567",
"locationId" : "DATALOAD",
"model" : "A505",
"subscriberId" : "",
"status" : "Stock",
"headendNumber" : "4"
}
{
"_id" : "P13050I",
"locationId" : "1423110302801",
"model" : "A505",
"subscriberId" : "37",
"status" : "Stock",
"headendNumber" : "4"
}
I will get more than 100 documents (rows) Equipment collection.
2.Subscriber
db.getCollection('Subscriber').find({})
{
"_id" : "5622351",
"equipment" : [
"0018015094E6",
"1234567",
"ADFB70878422",
"M10610TCB052",
"MA1113FHQ151"
]
}
{
"_id" : "490001508063",
"equipment" : [
"17616644510288",
"P13050I",
"M91416EA4251",
"128552270280560"
]
}
In the Subscriber collection, I need to remove (get all the id from Equipment collection loop it) only the matches equipment field.
Forex from the above result, I need to remove only "1234567", and "P13050I"
Expected output.
db.getCollection('Subscriber').find({})
{
"_id" : "5622351",
"equipment" : [
"0018015094E6",
"ADFB70878422",
"M10610TCB052",
"MA1113FHQ151"
]
}
{
"_id" : "490001508063",
"equipment" : [
"17616644510288",
"M91416EA4251",
"128552270280560"
]
}
Please help me, anyone.
You can use the following to update records.
Let's find records which need to deleted and store them in array
var equipments = [];
db.getCollection("Equipment").find({ $and: [
{ $where: 'this._id.length <= 7' },
{ "model": "A505"}
]}).forEach(function(item) => {
equipments.push(item._id)
})
Now, iterate over records of the second collection and update if required.
db.getCollection('Subscriber').find({}).forEach(function(document) => {
var filtered = document.equiment.filter(id => equipments.indexOf(id) < 0);
if(filtered.length < document.equipment.length){
db.getCollection('Subscriber').update({"_id": document.id }, { $set: {'equipment': filtered}})
}
})
.filter(id => equipments.indexOf(id) < 0) will keep entries which is not present in initially populated array equipments and it will persist if there is any change.

MongoDB- Add new field from existing array

I am the beginner of the MongoDB
Here I mentioned my database schema
{
"_id" : ObjectId("5e72067973c1241068a13647"),
"client_id" : "1001",
"dependent" : [
{
"dependent_name" : "asdsa",
"dependent_id" : "DE100"
},
{
"dependent_name" : "fdggd",
"dependent_id" : "DE101"
}
]
}
I want to add new field based on client_id and dependent_id
Here I mentioned My query but cannot able to get my expected result
db.collection.update({"client_id" : "1001","dependent.dependent_id":"DE101"}, {"$push": {"reason":"expired"}})
I am Expected Result is
{
"_id" : ObjectId("5e72067973c1241068a13647"),
"client_id" : "1001",
"dependent" : [
{
"dependent_name" : "asdsa",
"dependent_id" : "DE100"
},
{
"dependent_name" : "fdggd",
"dependent_id" : "DE101",
"reason":"expired"
}
]
}
so anyone help me to solve this
db.collection.update({"client_id" : "1001","dependent.dependent_id":"DE101"},
{$set:
{"dependent.$.reason":"expired"}})
Try this it works for me using $
As i am also new to mongodb, as i tried, i can give you suggestion to update whole document or replace it.
both way i tried, and query is as below.
Update
db.updateColl.update({ 'dependent.dependent_id': 'DE101' },
{
$set: {
"dependent": [
{
"dependent_name": "asdsa",
"dependent_id": "DE100"
},
{
"dependent_name": "fdggd",
"dependent_id": "DE101",
"reason": "expired"
}
]
}
});
Replace
db.updateColl.replaceOne({ 'dependent.dependent_id': 'DE101' }, {
"dependent": [
{
"dependent_name": "asdsa",
"dependent_id": "DE100"
},
{
"dependent_name": "fdggd",
"dependent_id": "DE101",
"reason": "expired"
}
]
})
may be it can help you. if any suggestion regarding it wellcome.

MongoDB query for a specific field within a document returns empty document

For each GSM subscriber, I have a document in "Service" collection and the part I'm querying is as below (Had to omit parts of the document and divide it into two sections since it was quite long), I'm trying to to fetch documentVerifiedDate where documentPurpose and serviceNumber are equal to specific values:
{
"_id": ObjectId("59abee12e4b044ce2d6001b6"),
"service": {
"serviceRequestId": "1335102",
"serviceIndex": "S0",
"accountIndex": "A0",
"serviceUser": {
"isServiceUserSameAsCustomer": "Y",
"isHolder": "N",
"isPayer": "N",
"profileDetails": {
"identificationDetails": {
"identificationDetail": [{
"idType": {
"masterCode": "PASS"
},
"documentPurpose": {
"masterCode": "POID"
},
"idNumber": "9339904299",
"isReceived": "Y",
"isVerified": "Y",
"documentReceivedDate": ISODate("2017-09-05T08:13:25.000+0000"),
"DMSReferenceNo": "85449499",
"documentVerifiedDate": ISODate("2017-09-05T08:13:25.000+0000")
},
{
"idType": {
"masterCode": "REGFORM"
},
"documentPurpose": {
"masterCode": "REGFORM"
},
"isUploaded": "Y",
"isReceived": "Y",
"isVerified": "Y",
"documentUploadedDate": ISODate("2017-09-05T08:13:25.000+0000"),
"DMSReferenceNo": "85449499",
"documentReceivedDate": ISODate("2017-09-05T08:13:25.000+0000"),
"documentVerifiedDate": ISODate("2017-09-05T08:13:25.000+0000")
},
{
"idType": {
"masterCode": "MMS"
},
"documentPurpose": {
"masterCode": "MMS"
},
"isUploaded": "Y",
"isReceived": "Y",
"isVerified": "Y",
"documentUploadedDate": ISODate("2017-09-05T08:13:25.000+0000"),
"DMSReferenceNo": "85449499",
"documentReceivedDate": ISODate("2017-09-05T08:13:25.000+0000"),
"documentVerifiedDate": ISODate("2017-09-05T08:13:25.000+0000")
}
]
},
and also:
"serviceDetails" : {
"serviceNumberCategory" : {
"masterCode" : "NORML"
},
"selfCareAccount" : "Y",
"contractDetails" : {
"startDate" : ISODate("2017-09-03T11:56:58.658+0000"),
"endDate" : ISODate("9999-12-31T00:00:00.000+0000")
},
"technology" : {
"masterCode" : "GSM"
},
"starterKitUpdated" : "Y",
"relatedProject" : "",
"businessType" : {
"masterCode" : "Prepaid"
},
"mobileMoneyAccount" : "Y",
"activatedVia" : {
"masterCode" : "SP"
},
"serviceType" : {
"masterCode" : "GSM"
},
"subServiceType" : {
"masterCode" : "Voice"
},
"serviceNumber" : "9339904299",
"simDetails" : {
I've written below query to fetch documentVerifiedDate where documentPurpose is POID and serviceNumber is 9339904299:
db.Service.find ({
"service.serviceDetails.serviceNumber": "9339902499",
"service.serviceUser.profileDetails.identificationDetails.identificationDetail.0.documentPurpose.masterCode" : "POID"
},
{
"service.serviceUsear.profileDetails.identificationDetails.identificationDetail.0.documentVerifiedDate" : 1,
_id: 0
})
and I'm getting below result:
{
"service" : {
}
}
I'd appreciate it if you could help me understand why above query does not serve the intended purpose, i.e. documentVerifiedDate is not returned.
I've used below link to write the query.
SQL to MongoDB Mapping Chart
From the docs,
$elemMatch, $slice, and $ are the only way to project specific
elements to include in the returned array. For instance, you cannot
project specific array elements using the array index; e.g. {
"instock.0": 1 } projection will not project the array with the first
element.
Use $ positional operator.
Something like
db.Service.find ({
"service.serviceDetails.serviceNumber": "9339904299",
"service.serviceUser.profileDetails.identificationDetails.identificationDetail.documentPurpose.masterCode": "POID"
},
{
"service.serviceUser.profileDetails.identificationDetails.identificationDetail.$": 1
})
This will give you the matching identificationDetail object and you can use the documentVerifiedDate from the document.
Note: serviceNumber in the query is not matching the provided document. I have adjusted query to use the serviceNumber from document.

MongoDB Aggregation Data

I am new to Mongo Aggregation and have this data
{
"_id": {
"$oid": "5654a8f0d487dd1434571a6e"
},
"ValidationDate": {
"$date": "2015-11-24T13:06:19.363Z"
},
"DataRaw": " WL 00100100012015-08-28 02:44:17+0000+ 16.81 8.879 1084.00",
"ReadingsAreValid": true,
"locationID": " WL 001",
"Readings": {
"pH": {
"value": 8.879
},
"SensoreDate": {
"value": {
"$date": "2015-08-28T02:44:17.000Z"
}
},
"temperature": {
"value": 16.81
},
"Conductivity": {
"value": 1084
}
},
"HMAC":"ecb98d73fcb34ce2c5bbcc9c1265c8ca939f639d791a1de0f6275e2d0d71a801"
}
My goal is to calculate the average temperature for every two hours interval, then per month, year and week. I have tried various queries but no luck. This is what i have tried so far
data.aggregate([{"$unwind":"$Readings"},
{"$project":{"HourRecord":{"$hour":"Readings.SensoreDate.value"},
"YearRecord":{"$year":"$Readings.SensoreDate.value"}}},
{'$group' : {'_id' : "$locationID",
'AverageTemp' : { '$avg' : '$Readings.temperature.value'}}}
])
and i got an empty results like this
{u'ok': 1.0, u'waitedMS': 0L, u'result': [{u'AverageTemp': None, u'_id': None}]}
I have tried several other combinations but still got empty results.
The following Queries Return the required result per hour, month etc but how to i group by two hours interval instead of one hour
test_Agg.aggregate([{"$unwind":"$Readings"},
{"$project":{ "HourRecord": { "$hour":"$Readings.SensoreDate.value"},
"YearRecord": {"$year":"$Readings.SensoreDate.value"},
"MonthRecord": {"$month":"$Readings.SensoreDate.value"},
"locationID" : 1,
"Readings.pH.value":1,
'Readings.temperature.value' : 1}
},
{'$group' : {'_id' :"$HourRecord",
'AverageTemp' : { '$avg' : '$Readings.temperature.value'}}
}])
The second pipeline $project in the query didn't project the required values used in the subsequent pipelines. Hence, the result was empty.
The required fields have been added in the $project. Try the below query.
db.temperature.aggregate([{"$unwind":"$Readings"},
{"$project":{ "HourRecord": { "$hour":"$Readings.SensoreDate.value"},
"YearRecord": {"$year":"$Readings.SensoreDate.value"},
locationID : 1,
'Readings.temperature.value' : 1}
},
{'$group' : {'_id' : "$locationID",
'AverageTemp' : { '$avg' : '$Readings.temperature.value'}}}
]);
Output for the one document provided in the post:-
{
"_id" : " WL 001",
"AverageTemp" : 16.81
}

Project with Match in aggregate not working after use substr in mongodb

I have face one use with mongodb.
below is my sample record.
{
"_id" : ObjectId("56fa21da0be9b4e3328b4567"),
"us_u_id" : "1459169911J4gPxpYQ7A",
"us_dealer_u_id" : "1459169911J4gPxpYQ7A",
"us_corporate_dealer_u_id" : "1459169173rgSdxVeMLa",
"us_oem_u_id" : "1459169848CK5yOpXito",
"us_part_number" : "E200026",
"us_sup_part_number" : "",
"us_alter_part_number" : "",
"us_qty" : 0,
"us_sale_qty" : 2,
"us_date" : "20160326",
"us_source_name" : "BOMAG",
"us_source_address" : "",
"us_source_city" : "",
"us_source_state" : "",
"us_zip_code" : "",
"us_alternet_source_code" : "",
"updated_at" : ISODate("2016-03-29T06:34:02.728Z"),
"created_at" : ISODate("2016-03-29T06:34:02.728Z")
}
I have try to get all recored having unique date
So, I have made below query using aggregate
.aggregate(
[
{
"$match":{
"yearSubstring":"2016",
"monthSubstring":"03",
"us_dealer_u_id":"1459169911J4gPxpYQ7A"
}
},
{
"$project":
{
"yearSubstring":{"$substr":["$us_date",0,4]},
"monthSubstring":{"$substr":["$us_date",4,2]},
"daySubstring":{"$substr":["$us_date",6,2]}
}
},
{
"$group":
{
"_id":{"monthSubstring":"$monthSubstring",
"yearSubstring":"$yearSubstring",
"daySubstring":"$daySubstring"
},
"daySubstring":{"$last":"$daySubstring"}
}
},
{"$sort":{"us_date":1}}
]
)
I have try both way to pass year and month (as string and as int)
but I have get blank result.
if I'm remove month and year from condition then record came.
mostly I have try all the diff. diff. solution but result is same.
Thank in advance.
You have written incorrect query.
You don't have yearSubstring and monthSubstring fields on this stage.
{
"$match":{
"yearSubstring":"2016",
"monthSubstring":"03",
"us_dealer_u_id":"1459169911J4gPxpYQ7A"
}
},
You should write as following:
.aggregate(
[
{
"$match":{
"us_dealer_u_id":"1459169911J4gPxpYQ7A"
}
},
{
"$project":
{
"yearSubstring":{"$substr":["$us_date",0,4]},
"monthSubstring":{"$substr":["$us_date",4,2]},
"daySubstring":{"$substr":["$us_date",6,2]}
}
},
{
"$match":{
"yearSubstring":"2016",
"monthSubstring":"03"
}
},
{
"$group":
{
"_id":{"monthSubstring":"$monthSubstring",
"yearSubstring":"$yearSubstring",
"daySubstring":"$daySubstring"
},
"daySubstring":{"$last":"$daySubstring"}
}
},
{"$sort":{"us_date":1}}
]
)
If you want to get other fields, you should include them into projection stage.