MongoDB Aggregate $ Project

I store our web server logs in MongoDB , and the diagram looks something like this:

[ { "_id" : 12345, "url" : "http://www.mydomain.com/xyz/abc.html", .... }, .... ] 

I am trying to use the $project operator to slightly change the shape of this schema before I start passing my collection along the aggregation pipeline. Basically, I need to add a new field called "type", which will later be used to perform group operations. The logic for the new field is pretty simple.

 if "url" contains "pattern_A" then set "type" = "sales lead"; else if "url" contains "pattern_B" then set "type" = "existing client"; ... 

I think it should be something like this:

 db.weblog.aggregate( { $project : { type : { /* how to implement the logic??? */ } } } ); 

I know how to do this using map-reduce (by setting the "keyf" attribute in a custom JS function that implements the above logic), but now I'm trying to use a new aggregation structure . I tried to implement the logic using expression operators, but still could not get it to work. Any help / suggestion would be greatly appreciated!

+6
source share
2 answers

I use my โ€œsolutionโ€ if others are facing the same needs as mine.

After researching for several weeks, as @ asya-kamsky suggested in one of my comments, I decided to add the computed field to my original MongoDB schema. This is not ideal, because whenever the logic for the calculated field changes, I will have to do massive updates to update all the documents in my collection, but that was either that or rewrite my code to use MapReduce. At the moment, I have chosen the first. If you look at the Jira MongoDB board, it would turn out that many people asked for more diverse statements for the $ project operator, and I certainly hope the MongoDB development team gets around to adding them sooner rather than later

Operator for separating a string based on a separator.

New $ elemMatch design statement

Allow $ slice operator in $ project

add the $ inOrder statement to $ project

+1
source

You need to use a combination of several operators and expressions.

firstly, the $cond operator in $project allows you to implement, if then still logic.

$cond : takes an array of three elements, first a logical expression, the second and third values โ€‹โ€‹used for the field value - if the logical expression is true, then it uses the second element for the value, if not the third element.

you can nest them so that the third element itself is a $cond expression to get if-then-else-if-then-etc.

String manipulation is a little awkward, but you have $substr .

If you post some examples of exactly what you tried, I can determine why this did not work.

0
source

All Articles