08-04-2022 12:29 PM
Hi Team,
I wanted to understand more about Router snap as I was stuck routing data today. Let’s assume I’m reading a flat file with 100 records and the file has 3 columns, ID (can have duplicates), Name, and Phone Number.
I want to route the data where ID = 130 and rest others, how do I achieve this?
As I want both the data for different transformations, can’t use a filter snap and that’s where router helps.
The first condition would look like $ID == 130, what would the other condition look like to consider all the remaining records.
I don’t want to write $ID !=130; reason being, my actual use case has a lot of conditions, so I want either 100 or others. I did try with true
and false
but it didn’t seem to work for me.
In addition to this, I wanted to learn whether we can write a nested condition in router, e.g.
$Name == null || $PhoneNumber== null || $Name == null && $PhoneNumber== null
Would the above work as expected?
Expectation is:
Route all records whose Name is Null OR Phone Number is Null OR both Name & Phone Number is Null
Appreciate your help and time on this one.
Regards,
Darsh
Solved! Go to Solution.
08-05-2022 05:40 PM
@darshthakkar, look at it this way.
The router is sort of like a chain of ‘IF’ statements.
Without “first match”, it’s like multiple “if’s” in a row, so that sending a document down the first Route doesn’t preclude routing it to, say, the third Route…
if ( $doc.lastName == "Munster" || $doc.lastName == "Kolchak" )
route_to_path(doc, "Monster shows");
if ( $doc.lastName == "Kirk" )
route_to_path(doc, "SF shows");
if ( $doc.lastName == "Munster" || $doc.lastName == "Seinfeld" )
route_to_path(doc, "Comedy shows");
In the pseudocode above, if doc.lastName is “Munster”, a copy of the doc will be routed to both the “Monster shows” path and the “Comedy shows” path.
Now, by turning on “First match”, you tell it “route the document only down the first Route where the Expression is true. Stop there and don’t route that document down other routes. If no route’s expression is true, just dump the document into the void.”
That’s like putting an “ELSE” in front of each of the “IF” statements except the first.
if ( $doc.lastName == "Munster" || $doc.lastName == "Kolchak" )
route_to_path(doc, "Monster shows");
else if ( $doc.lastName == "Kirk" )
route_to_path(doc, "SF shows");
else if ( $doc.lastName == "Munster" || $doc.lastName == "Seinfeld" )
route_to_path(doc, "Comedy shows");
If doc.lastName is “Munster” it will route to “Monster shows” and nothing else. It will never get to case number 3. If doc.lastName is “Forbin” it won’t match any of the expressions, and the doc won’t be routed anywhere – it will just evaporate.
Okay, so why does @alex.panganiban.guild recommend using “First match” and setting the last item to “true”? Can’t we just say $ID == 130
and $ID != 130
??
Well, we can. But we’d rather not.
To see why, convert it to pseudocode again:
if ( $ID == 130 )
route_to_path(doc, "130 path");
if ( $ID != 130 )
route_to_path(doc, "Everything else path");
That works fine.
Then some other developer comes along and sees that the values “42” and “153” also need special processing. Let’s say they’re OCD and they put everything in numerical order:
if ( $ID == 42 )
route_to_path(doc, "42 path");
if ( $ID == 130 )
route_to_path(doc, "130 path");
if ( $ID == 153 )
route_to_path(doc, "153 path");
if ( $ID != 130 )
route_to_path(doc, "Everything else path");
Whoops! ID’s 42 and 153 continue to be routed down the “Everything else” path in addition to their own new paths.
Now, let’s turn on “First match” and lets put the last expression as simply true
.
We get:
if ( $ID == 42 )
route_to_path(doc, "42 path");
else if ( $ID == 130 )
route_to_path(doc, "130 path");
else if ( $ID == 153 )
route_to_path(doc, "153 path");
else if ( true )
route_to_path(doc, "Everything else path");
This does what we want, and avoids future bugs when the snap gets changed.
And else if ( true )
is just a different way of saying else
.
You do not want “First match” if you need to route the same document down multiple paths. For a contrived example, suppose the documents refer to people, and you have special processing of one type for married-vs-single, and some other kind of processing for male-vs-female. That’s 4 different routes, and a copy of each doc will always be routed down exactly two of those paths (assuming all docs are only male/female and married/single).
Hope this helps!
08-05-2022 01:25 PM
In that case, I would definitely use the ‘first match’ feature. this way the ID=130 records won’t also go into the ‘all others’ output view as well.
08-05-2022 05:40 PM
@darshthakkar, look at it this way.
The router is sort of like a chain of ‘IF’ statements.
Without “first match”, it’s like multiple “if’s” in a row, so that sending a document down the first Route doesn’t preclude routing it to, say, the third Route…
if ( $doc.lastName == "Munster" || $doc.lastName == "Kolchak" )
route_to_path(doc, "Monster shows");
if ( $doc.lastName == "Kirk" )
route_to_path(doc, "SF shows");
if ( $doc.lastName == "Munster" || $doc.lastName == "Seinfeld" )
route_to_path(doc, "Comedy shows");
In the pseudocode above, if doc.lastName is “Munster”, a copy of the doc will be routed to both the “Monster shows” path and the “Comedy shows” path.
Now, by turning on “First match”, you tell it “route the document only down the first Route where the Expression is true. Stop there and don’t route that document down other routes. If no route’s expression is true, just dump the document into the void.”
That’s like putting an “ELSE” in front of each of the “IF” statements except the first.
if ( $doc.lastName == "Munster" || $doc.lastName == "Kolchak" )
route_to_path(doc, "Monster shows");
else if ( $doc.lastName == "Kirk" )
route_to_path(doc, "SF shows");
else if ( $doc.lastName == "Munster" || $doc.lastName == "Seinfeld" )
route_to_path(doc, "Comedy shows");
If doc.lastName is “Munster” it will route to “Monster shows” and nothing else. It will never get to case number 3. If doc.lastName is “Forbin” it won’t match any of the expressions, and the doc won’t be routed anywhere – it will just evaporate.
Okay, so why does @alex.panganiban.guild recommend using “First match” and setting the last item to “true”? Can’t we just say $ID == 130
and $ID != 130
??
Well, we can. But we’d rather not.
To see why, convert it to pseudocode again:
if ( $ID == 130 )
route_to_path(doc, "130 path");
if ( $ID != 130 )
route_to_path(doc, "Everything else path");
That works fine.
Then some other developer comes along and sees that the values “42” and “153” also need special processing. Let’s say they’re OCD and they put everything in numerical order:
if ( $ID == 42 )
route_to_path(doc, "42 path");
if ( $ID == 130 )
route_to_path(doc, "130 path");
if ( $ID == 153 )
route_to_path(doc, "153 path");
if ( $ID != 130 )
route_to_path(doc, "Everything else path");
Whoops! ID’s 42 and 153 continue to be routed down the “Everything else” path in addition to their own new paths.
Now, let’s turn on “First match” and lets put the last expression as simply true
.
We get:
if ( $ID == 42 )
route_to_path(doc, "42 path");
else if ( $ID == 130 )
route_to_path(doc, "130 path");
else if ( $ID == 153 )
route_to_path(doc, "153 path");
else if ( true )
route_to_path(doc, "Everything else path");
This does what we want, and avoids future bugs when the snap gets changed.
And else if ( true )
is just a different way of saying else
.
You do not want “First match” if you need to route the same document down multiple paths. For a contrived example, suppose the documents refer to people, and you have special processing of one type for married-vs-single, and some other kind of processing for male-vs-female. That’s 4 different routes, and a copy of each doc will always be routed down exactly two of those paths (assuming all docs are only male/female and married/single).
Hope this helps!
08-06-2022 09:02 AM
Thank you @ForbinCSD for the detailed explanation. It was super helpful. I now understand the importance of “First Match” as well as how ordering of the conditions in router is so vital.
Thank you again for your help. @alex.panganiban.guild also deserves the credit behind this solution so THANK YOU @alex.panganiban.guild .
Closing this thread now.