Hello FME'ers,
Because Friday is a holiday this week, you get the question-of-the-week post a little early.
Question of the WeekThis question from @rmm7 came up yesterday and relates to testing and filtering data:
Q) I'm trying to match values between two attributes on the same feature.
I have an electric transformer with a phase value, and it's connected electric cable, also with a phase value. The phase values can be any combination of A,B, or C. For example, the electric transformer might have a value of AC, and the cable it's joined to has a value of ABC.
I'm trying to find a way to test if the phase values of the transformer are contained within the phase values of the cable.
A) This question got a number of answers. But in working out my version I came up with an idea and thought I'd share it.
If you don't want to go through the whole thought process, then just skip to the Summary section.
Otherwise, let's start by looking at what exactly we're trying to do...
Question Requirements
So there is an electric transformer and a cable. Each has a list of phase values. We need to know if the transformer values are stored within the cable values.
So, for example:
- Cable Phases: A,B,C
- Transformer Phases: A, C
- Result: Passed
But:
- Cable Phases: A,C
- Transformer Phases: B, C
- Result: Failed
In short, we need to match lists of values, and you can't really do that by default in the Tester.
ApproachesThere are two ways to approach a problem like this.
Firstly, we can go for a generic approach, where we try to solve the problem of list matching, without restriction. So the solution would work for any list, not just the examples here.
Secondly, we can go for a focused approach, where we try to solve the problem using the limits specified by the user. In this case, "the phase values can lonly] be any combination of A,B, or C", plus from the examples shown, I assume the values are always in alphabetical order.
This makes the task easier because there are only a set number of matches.
By my calculations there are only 7 values (A/B/C/A,B/A,C/B,C/A,B,C). As @erik_jan points out, the Tester CONTAINS operator eliminates most of those. Only A,C is difficult because it's the only possibility not contained within the full A,B,C string.
So something like this:
...should be fine. Great reasoning and a nice answer.
So why is my question title about Lists and the InlineQuerier?
A Generic Approach using ListsPersonally, I looked for a generic approach because you get a solution that works for many scenarios.
Plus, the generic approach is often the same as the focused approach, so it doesn't matter anyway.
Here the core problem is:
Problem: It's not easy to test multiple values in one string, against multiple values in another string.
OK, if we can't test the values in that structure, can we restructure them to something easier? If you've got comma-separated values (like A,B,C) the simplest transformation is to put them into an FME List attribute.
So I add two AttributeSplitters:
And now I have list attributes, phaseList1{} and phaseList2{}, say like this:
phaseList1{0} = A
phaseList1{1} = B
phaseList1{2} = C
phaseList2{0} = A
phaseList2{1} = C
Problem: It's not much more easy to test multiple values in one list, against multiple values in another list.
What I could do is create a custom transformer and check all the values in phaseList2{} for their equivalent in phaseList1{}. I'd need a loop with a ListSearcher to do the actual testing.
But custom transformers and loops seems a bit complicated for this. Is there a better way?
A Generic Approach using RegexMy next idea was to use Regex and this is the solution I posted to the question. @ebygomm came up with a Regex solution too.
My version was:
0 != -1
Her's was:
0
As @redgeographics says, creating Regex on the fly must be the ultimate FME hack. To be fair I think both solutions are quite horrific! Mine was mostly a cut-and-paste job from StackOverflow and is not fully generic. Plus, I hate to create regex.
So what else do we have?
A Generic Approach using SQLCould we use SQL? It has the advantage of a single line of "code" and be fairly readable too.
But how do I get the attributes into a database and what do I use to query them? I'd need to have several tables all joined together with keys, and how do I set that up?
I use a single transformer: the InlineQuerier:
This is the million dollar idea I wanted to share!
If I explode the list and send it as a separate connection to the InlineQuerier I have a scenario where I can build a single SQL query where all entries in List B join with an entry in List A.
Problem: My SQL skills are rusty through lack of use.
I think the technique is sound, it's just that I can't figure out how to structure the SQL. So far I have:
select distinct "ID" from "List B" where (select count(*) from "List B" where "xList" in (select "pList" from "List A")) = (select count(*) from "Main Data" as m join "List B" as lb on m.ID = lb.ID)
Yikes! It works, but only for one feature, and it looks pretty sad. Maybe someone with better SQL skills can improve it?
Still, using SQL has opens up a lot of possibilities.
SummaryOverall, I think this is an interesting question that shows the different approaches we can take towards solving a particular need.
But what I really wanted to pass on was the idea of exploding a list and sending it into an InlineQuerier as a separate input.
Here I have two lists, so I split them off, keeping the original stream in case I need it. This way I get multiple database tables, automatically, and can run a query that combines all elements of them.
It even lets me query between previous/subsequent features, without using the Adjacent Feature processing.
When I think of the transformations I've tried to do on a list, it seems to me that they could be much easier using SQL. As new FME users know more SQL than FME transformers, it could help.
Let me know below what you think.
Other Notable QuestionsA series of Virtual Roadshow webinars took place this week, so I thought I'd share a few of the questions asked:
Desktop/Engine- Is there a maximum number of transformers that can be used in a workspace?
- Managing the workspace is likely to be an issue before you reach an FME limit. We've seen workspaces with more than 7,000 transformers, but breaking that into separate parts would be better.
- Is the HTTPCaller able to upload workspace results as a file to cloud storage services?
- It could if you use a FeatureWriter and the service has a REST API. We have a set of transformers to help with that as well depending on the service: S3Connector, BoxConnector, DropboxConnector, etc
- Are transformer presets for one workbench, or across many?
- They are global, so once you create a preset it will be available in all workspaces
- I get nervous using transformers from the HUB for production workspaces. How well supported are these transformers?
- If you use ones from the Safe Official Publisher then you can trust that we would be supporting these. You can verify by going to the hub transformer page for the transformer you want and check the publisher.
- Are there plans for a dedicated Jira Reader/Writer?
- I love this idea. We are doing things in house with Jira and FME, and can examine making it available on the FME Hub.
- Speaking of packages in the FME Hub… when will the Google Sheets update be available?
- It is getting close. I'd suggest another month or so as a wild guess.
- I need FME to be able to read .fit / .fits files. These are astronomical images in native format and is much preferable to converting to TIFF's.
- You should post this as an idea (on knowledge.safe.com) where it can gain upvotes from other users. If enough users want it, then who knows (the sky's the limit - or not!). Also, since GDAL supports FITS, we can likely make it work fairly easily.
- Automations are great but when would you use Automations as opposed to a scheduled workspace(s)?
- You can make this decision on a per schedule basis. Automations are nice if you want to trigger multiple workspaces in parallel, or start job chaining or adding external actions.
- What license for AWS do you need to use amazon rekognition?
- You'll need to set up a rekognition account to generate an access key id and token
- Can i use a Zapier trigger as a webhook in fme server?
- Yes, I think you could do that as long as Zapier is able to send a request to your FME Server. We demonstrated this a number of years ago. It was not all that hard back then, and I suspect would only be easier today.
- With FME Apps, can we use a login with FME 2020?
- Yes, Apps in 2020 have an option to require users log in to use the app.