0

I've a got a mongodb database, which contains records of domains, and the integer number of 'hits' each has been seen.

record =
{
"dom" : "Somedomain.com",
"hits" : 23
}

I want to write some mongodb stored procedures to process these records on the server. MongoDb can store procedures in javascript.

I want to (to give a trivial example) get the aggregate of the number of hits for two domains. In Python/pymongo I can do this easily - I can get the db.find({"dom": "domainname.com"}) the records for the two domains, parse the returned record as JSON, extract the hit numbers, and add them.

However, I can't seem to do the same in javascript. Part of the problem seems to be that find return BSON, not JSON, and there seems to be no native way to convert it.

> This is in the Mongo Shell, which is mostly javascript.

> var r = db.test_collection.find({dom:"somedomain.com"},{hits:true,_id:false})
> r
{ "hits" : 1043 }
> var j = JSON.parse(r)
2016-03-03T17:27:52.046-0500 SyntaxError: Unexpected token D

> var r = db.test_collection.find({dom:"somedomain.com"},{hits:true,_id:false}).valueOf() 
> r
{ "hits" : 1043 }
> var j = JSON.parse(r)
2016-03-03T17:27:52.046-0500 SyntaxError: Unexpected token D

The source of this 'SyntaxError' seems to be BSON vs JSON

> var r = db.test_collection.find({dom:"somedomain.com"},{hits:true,_id:false}).valueOf()
> r.hits
>

I can't get the 'hits' value out where I can use it.

I can do this trivially in Python with Pymongo, but not in mongo shell, nor in javascript.

I want the stored javascript procedures to be able to retrieve values from the db, and process them, finally returning a result. But I can't get to the actual value (hit number, in this case) to do so. Anyone?

1
  • mongodb does not support stored procedures. I'll suggest to elaborate your question with some sample mongodb documents. Also post what do you expect from action you are trying to perform
    – Saleem
    Commented Mar 3, 2016 at 22:51

1 Answer 1

1

I think MongoDB aggregation might be what you're looking for.

You'd do something like this:

db.test_collection.aggregate( [
   { $group: { _id: "$dom", total: { $sum: "$hits" } } },
   { $match: { dom: { $or: ['somedomain.com', 'anotherdomain.com'] } } }
] )

The above is just a simple example, and I don't know the exact structure of all your data, so you may have to tweak it a bit. The MongoDB docs provide a great aggregation example related to zipcodes and city population:

db.zipcodes.aggregate( [
   { $group: { _id: { state: "$state", city: "$city" }, pop: { $sum: "$pop" } } },
   { $group: { _id: "$_id.state", avgCityPop: { $avg: "$pop" } } }
] )

Also, keep in mind, you shouldn't have to do var j = JSON.parse(r). MongoDB queries return plain old JavaScript objects.

3
  • Glad someone mentioned the "plain old JavaScript objects". The whole JSON/BSON thing gets overdone, where "often" ( not always ) the case is that people only need be concerned with the native "object" implementation of the language they are using. Or for most strongly typed languages that lack that, the object format returned and supported by the driver. Also kudos for seeing the question within the question and providing something that solves it. Commented Mar 3, 2016 at 23:17
  • 1
    @BlakesSeven yeah in most cases, developers should never really be concerned with BSON/JSON. Drivers/libraries usually handle that layer of abstraction.
    – Josh Beam
    Commented Mar 3, 2016 at 23:19
  • Thanks Josh, but I think I need to clarify - 'add the hit values' was just given as a very simple example. i want to create some fairly complex server side functionality, well beyond the built in functions of MongoDB. I'll look into the other suggestions. Commented Mar 4, 2016 at 14:10

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.