0

I have a collection containing data:

{
  "_id" : ObjectId("51dfb7abe4b02f15ee93a7c7"),
  "date_created" : "2013-7-12  13:25:5",
  "referrer_id" : 13,
  "role_name" : "Physician",
  "status_id" : "1",

}

I am sending the query:

cmd {
    "mapreduce" : "doctor" ,
    "map" : "function map(){emit(this._id,this);}" ,
    "reduce" : "function reduce(key,values){return values;}" ,
    "verbose" : true ,
    "out" : { "merge" : "map_reduce"} ,
    "query" : { "$where" : "this.demographics.first_name=='makdoctest'"}
}

I am getting error as:

"errmsg" : "exception: count failed in DBDirectClient: 10071 error on invocation of $where function:\nJS Error: TypeError: this.demographics has no properties nofile_a:0"
Phalguni Mukherjee
  • 623
  • 3
  • 11
  • 29
  • 2
    It means that somewhere in one of your documents `demographics` is `null` or does not exist, you need to do a null check first, but more importsantly why are you dong this in a $where, it is like the 3rd time you have abused the $where operator – Sammaye Jul 31 '13 at 12:42
  • @Sammaye why comment, make it an answer – Roman Pekar Jul 31 '13 at 12:44
  • Why are you using `$where`? It's slow and difficult to read and maintain. – Leonid Beschastny Jul 31 '13 at 12:45
  • its the requirement of the customer, who want's both the operation to be the part of the api. – Phalguni Mukherjee Jul 31 '13 at 12:47
  • @RomanPekar Even though the comment does kind of answer tbh it is a bad answer, the right answer is to get rid of that `$where` – Sammaye Jul 31 '13 at 12:48
  • How `javascript` string is better than `json` string in terms of API? – Leonid Beschastny Jul 31 '13 at 12:51
  • as I told in one of my earlier question, we are making an interface to mongo db and user want's to query something like sql example:"foo.aaa>5 && foo.qty<7||xxx.aaa=='rrr'" – Phalguni Mukherjee Jul 31 '13 at 12:53
  • No matter how you play this, the user can abuse your openness and use it to create errors within the JS environemnt (if they are being benign). – Sammaye Jul 31 '13 at 12:56

1 Answers1

1

As Sammaye says in a comment:

It means that somewhere in one of your documents demographics is null or does not exist, you need to do a null check first, but more importantly why are you dong this in a $where?

I would go even further that that, and I wouldn't even use the Map/Reduce mechanism here. It slow, can't use indexes and can not run in parallel with others.

You would be much better off using the Aggregation Framework where you can do something like:

db.doctor.aggregate( [
    { $match: { "demographics.first_name" : 'makdoctest' } },
    { $group: …

You didn't specify the final goal here, but once you do I can update the answer.

Derick
  • 35,169
  • 5
  • 76
  • 99
  • Indeed the aggregation framework (provided his reuslts are under 16meg) is easily the better answer over even getting rid of the `$where` – Sammaye Jul 31 '13 at 13:01
  • @Sammaye aggregate does , but I want to query multiple collection in one short and return the data, Aggregate does it for one collection and the result is inline, we cannot store temporarily the data of each collection.and I need to store it temporarily, as my different collection may have same id field so i need to merge all those data, If some way I can store it in temp collection through aggregate, I am ok with aggregate, but I didn't found anything in mongo db document. – Phalguni Mukherjee Jul 31 '13 at 13:06
  • 1
    @PhalguniMukherjee Hmm it is really hard without looking at what your doing, I think that's the reply I was gonna make the last time you told me that but I got distracted by other questions. But MRs are really bad for JOINing data, you would better off doing it client side in your app if I am honest – Sammaye Jul 31 '13 at 13:07
  • Its a cloud based service and client is totally unaware of how the data is their, he receives data in a common format every time. – Phalguni Mukherjee Jul 31 '13 at 13:09
  • @PhalguniMukherjee Hmm I see what your trying to do, your trying to create a thin client on the cloud end that can pretty much take a query with no translation, unfortunately this is gonna give you a world of security problems, you have just encountered one – Sammaye Jul 31 '13 at 13:11
  • You can **not** query from multiple collections at the same time reliably. Operations in MongoDB are always on **one** collection. You need to do this in your application. – Derick Jul 31 '13 at 13:12
  • @Sammaye you are right, but no other option I guess, currently I have to go with this. – Phalguni Mukherjee Jul 31 '13 at 13:13
  • @Derick I am doing it through my application and all are "Map" reducing it to the same temporary collection. – Phalguni Mukherjee Jul 31 '13 at 13:14
  • @Derick You can do a nasty version of mring one collection then another in seprarate mrs and then merging the second mr down to the reuslting collection of the first mr, it is a nasty way but people are really despereate to do server-side joins at times – Sammaye Jul 31 '13 at 13:26
  • 1
    @Sammaye You can do that, but it's a really bad idea. People should learn to design their schemas properly! – Derick Jul 31 '13 at 13:37
  • @Derick even though every possible efforts are taken to club the data together as where required, but in certain condition, we are helpless specially in the scenario as an example like you want to do data analysis of historical data. – Phalguni Mukherjee Jul 31 '13 at 14:33
  • @Derick just trying to understand what can be the drawback of doing so, don't know much about hadoop, but guess hadoop's map reduce is capable of merging data from entire database, so can't we do by merging data from entire database? – Phalguni Mukherjee Jul 31 '13 at 16:55