Why does MapReduce return undefined for a field that exists in document? - mongodb

I am trying to debug a strange issue I am running into while running mapreduce on a collection:
For reference, here's a single document from the collection:
{
"_id" : "ITOUXFWgvWs",
"source" : "youtube",
"insert_datetime" : ISODate("2017-04-06T22:27:43.598Z"),
"processed" : false,
"raw" : {
"id" : "ITOUXFWgvWs",
"etag" : "\"m2yskBQFythfE4irbTIeOgYYfBU/hiQtS6aptLlqxTpsYp1EJIRcoZo\"",
"snippet" : {
"publishedAt" : ISODate("2017-04-06T13:25:28Z"),
"title" : "Alarm.com: The Only Smart Home App You Need",
"channelId" : "UC_HZfoZUP36STk7SrtKYH4g",
"description" : "All these new connected devices are awesome, but wouldn’t it be great if you could use one app for the entire connected home? It can all come together with Alarm.com.",
"categoryId" : "28",
"channelTitle" : "Alarm.com",
"thumbnails" : {
"default" : {
"height" : 90,
"width" : 120,
"url" : "https://i.ytimg.com/vi/ITOUXFWgvWs/default.jpg"
},
"standard" : {
"height" : 480,
"width" : 640,
"url" : "https://i.ytimg.com/vi/ITOUXFWgvWs/sddefault.jpg"
},
"high" : {
"height" : 360,
"width" : 480,
"url" : "https://i.ytimg.com/vi/ITOUXFWgvWs/hqdefault.jpg"
},
"medium" : {
"height" : 180,
"width" : 320,
"url" : "https://i.ytimg.com/vi/ITOUXFWgvWs/mqdefault.jpg"
},
"maxres" : {
"height" : 720,
"width" : 1280,
"url" : "https://i.ytimg.com/vi/ITOUXFWgvWs/maxresdefault.jpg"
}
},
"liveBroadcastContent" : "none",
"localized" : {
"title" : "Alarm.com: The Only Smart Home App You Need",
"description" : "All these new connected devices are awesome, but wouldn’t it be great if you could use one app for the entire connected home? It can all come together with Alarm.com."
}
},
"contentDetails" : {
"duration" : "PT37S",
"dimension" : "2d",
"definition" : "hd",
"licensedContent" : false,
"projection" : "rectangular",
"caption" : "false"
},
"kind" : "youtube#video",
"statistics" : {
"likeCount" : "0",
"dislikeCount" : "0",
"favoriteCount" : "0",
"viewCount" : "32"
},
"uploaded" : ISODate("2017-04-06T13:25:28Z")
},
}
I am literally following the mapreduce debug steps from official mongo documentation.
Here's what my mapreduce script looks like:
var map = function() {
emit("1", this._id);
};
var emit = function(key, value) {
print("emit");
print("key: " + key + " value: " + tojson(value));
}
var myDoc = db.getCollection("abc").find({}).limit(1);
map.apply(myDoc);
And it always produces the result like this:
MongoDB shell version: 2.4.6
connecting to: test
emit
key: 1 value: undefined
I expect the script to emit the _id since it clearly exists in the document but it doesn't.
What might be possible cause of this?

find() always returns a cursor.
Replace it with findOne()
var myDoc = db.getCollection("abc").findOne({});
Or store the documents in an Array using toArray()
var myDoc = db.getCollection("abc").find({}).limit(1).toArray()[0];

Related

mongodb lookup giving empty array

BED_MAST this is my one collection bed_mast contains WARD_ID and want to perform join to my other collection with is WARD_MAST given below.
{
"_id" : ObjectId("5e53c95a26b0e5ad0fb46376"),
"Bed_id" : "bd-10",
"WARD_ID" : "4",
"OCCUPIED" : "0",
"BED_TYPE" : "single AC"
}
{
"_id" : ObjectId("5e53c95a26b0e5ad0fb46377"),
"Bed_id" : "bd-11",
"WARD_ID" : "1",
"OCCUPIED" : "0",
"BED_TYPE" : "single Non AC"
}
WARD_MAST this is my WARD_MAST having ward_id. but while I am putting lookup I am not getting any data.
{
"_id" : ObjectId("5e53c95b26b0e5ad0fb46544"),
"patient_id" : null,
"ward_id" : 1,
"total_beds" : 55,
"ward_name" : "Ward 1"
}
{
"_id" : ObjectId("5e53c95d26b0e5ad0fb46545"),
"patient_id" : null,
"ward_id" : 2,
"total_beds" : 63,
"ward_name" : "Ward 2"
}
MY query is
db.BED_MAST.aggregate([{$lookup:{'from':"WARD_MAST",'localField':"WARD_ID",'foreignField':"ward_id",'as':"lookup_value"}}]).pretty()
output: I have confirmed the data by running this query to MySQL there it is working fine
{
"_id" : ObjectId("5e53c95b26b0e5ad0fb46388"),
"Bed_id" : "bd-28",
"WARD_ID" : "6",
"OCCUPIED" : "0",
"BED_TYPE" : "NICU",
"lookup_value" : [ ]
}
SAMPLE VALUES DATA IS GIVEN ALL DATA IS NOT POSSIBLE TO GIVE. I know it was asked 1000 times but not able to resolve this question. tried to solve with lookup. but it showing blank space. Is anything I am missing.
The problem is BED_MAST collection's WARD_ID has string values and WARD_MAST collection's ward_id has Number values.

Mongodb update and delete operations in a single query

I have documents in which I would like to update the hostUser with one of the members of the document,also have to delete the record from the member document and add the chips of the deleted member in the club chips.
Here is the sample document.
{
"_id" : "1002",
"hostUser" : "1111111111",
"clubChips" : 10000,
"requests" : {},
"profile" : {
"clubname" : "AAAAA",
"image" : "0"
},
"tables" : [
"SJCA3S0Wm"
],
"isDeleted" : false,
"members" : {
"1111111111" : {
"chips" : 0,
"id" : "1111111111"
},
"2222222222" : {
"chips" : 0,
"id" : "2222222222"
}
}
}
This is what I have tried.
db.getCollection('test').updateMany({"hostUser":"1111111111"},
{"$set":{"hostUser":"2222222222"},"$unset":{"members.1111111111":""}})
This is how you would handle unset and set in a single call to updateMany. Can you please clarify what you meant by "check if the values exist in the member field"?
db.getCollection('test').updateMany(
{"hostUser":"1111111111"},
{
'$set': {"hostUser":"2222222222"} ,
'$unset': {"members.1111111111":""}
}
)

Spring data mongo remove element in sub collection

I have this document:
{
"_id" : ObjectId("5a698b8bc2539428e3738c7d"),
"_class" : "com.xxx.xxx.inf.dao.mongo.domain.IndexDO",
"product_id" : "5a67fde8c2539414b9712482",
"cn_name" : "index - test",
"en_name" : "test index - test",
"sample_desc" : "this is a sample description",
"people_type" : 1,
"ref_literature" : [
{
"_class" : "com.xxx.xxx.inf.dao.mongo.domain.RefLiterature",
"_id" : null,
"name" : "ref 1"
},
{
"_class" : "com.xxx.xxx.inf.dao.mongo.domain.RefLiterature",
"_id" : null,
"name" : "ref 2"
}
],
"user_id" : 6,
"gmt_create" : ISODate("2018-01-25T07:47:23.800+0000"),
"detail_desc" : null,
"gmt_modified" : ISODate("2018-01-25T07:49:50.923+0000"),
"index_level" : [
{
"_class" : "com.xxx.xxx.inf.dao.mongo.domain.IndexLevel",
"_id" : ObjectId("5a72c83050abd32e7e54340d"),
"up_val" : "3.2",
"down_val" : "5.7",
"calc_symbol_type" : 2,
"level_desc" : "this is a test level desc"
}
]
}
I want to delete the element in index_level, and in here is:
{
"_class" : "com.xxx.xxx.inf.dao.mongo.domain.IndexLevel",
"_id" : ObjectId("5a72c83050abd32e7e54340d"),
"up_val" : "3.2",
"down_val" : "5.7",
"calc_symbol_type" : 2,
"level_desc" : "this is a test level desc"
}
I can remove this sub document in mongo shell with the command:
db.index.update(
{"_id":ObjectId("5a698b8bc2539428e3738c7d")},
{$pull:{"index_level": {"_id":ObjectId("5a72c83050abd32e7e54340d")}}}
)
But when I removed use mongotemplate code in below, I was failed to do this:
mongoTemplate.updateFirst(
Query(Criteria.where("_id").`is`(ObjectId("5a698b8bc2539428e3738c7d"))),
Update().pull("index_level", Query(Criteria.where("_id").`is`(ObjectId("5a72c83050abd32e7e54340d")))),
IndexDO::class.java
)
and tried below code:
mongoTemplate.updateFirst(
Query(Criteria.where("_id").`is`(ObjectId("5a698b8bc2539428e3738c7d")).and("index_level._id").`is`(ObjectId("5a72c83050abd32e7e54340d"))),
Update().pull("index_level", Query(Criteria.where("_id").`is`(ObjectId("5a72c83050abd32e7e54340d")))),
IndexDO::class.java
)
and finally, I can remove this sub document with this code:
mongoTemplate.updateFirst(
Query(Criteria.where("index_level._id").`is`(ObjectId("5a72c83050abd32e7e54340d"))),
Update().pull("index_level", Query(Criteria.where("_id").`is`(ObjectId("5a72c83050abd32e7e54340d")))),
IndexDO::class.java)
But this code has a problem, because in here the position field is _id, when I change the position field like "calc_symbol_type", the final code will remove all calc_symbol_type equals to the value which I send to the method.
So the question is where I was wrong? and the mongo shell command converts to mongotemplate code will be what?
Thanks !

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!!!

Fetching one element of array with sibling items (Without using aggregation or putting other sibling's value 1)

"translation" : [
{
"language" : "english",
"name" : "shahid Afridi",
"desc" : "batsmen",
"player" : "capten"
},
{
"language" : "spanish",
"name" : "shhid Ofridi",
"desc" : "batsmeen",
"player" : "capteen"
},
{
"language" : "french",
"name" : "hhid afrede is best",
"desc" : "batsmin",
"player" : "captn"
}
],
"auto-publish" : "publish",
"color" : "red",
"boolean" : "true"
I have this document in mongodb
In return
i want translation[0] with auto-publish, color and boolean.
Note: Without using aggregation or putting other sibling's value 1
You can use forEach on your cursor:
db.test.find({}).forEach(function(doc){
if (doc.hasOwnProperty('translation')){
var newdoc = {};
newdoc = doc.translation[0];
newdoc['auto-publish'] = doc['auto-publish'];
newdoc['color'] = doc['color'];
newdoc['boolean'] = doc['boolean'];
print(tojson(newdoc));
}
})
I don't think there's any other way to re-organize document as you need without using aggregation.