Servoy webinar series part 1: svySearch module
Servoy webinar series part 1: svySearch module
So today’s topic is a very interesting module that Sean and other server engineers have been developing over the past months and we have already released. So you can already download this search API and it makes it very easy to add a generic search to your existing or to your new server application. So Sean is going to talk about the background of this module and then he’s going to demonstrate on how you would use and implement this module. So Sean, are you ready to start the presentation? I’m as ready as I’ll ever be. Excellent. That is very good. Let me make you the presenter. All right. Let me go. Okay. Sean, can you see my screen? Yes, it is clearly visible. Okay. Good. Yeah. So this, just a quick background. I’m going to show you a module that was originally conceived for a Servoy world concept car, which is one of the sessions we do at Servoy world where we sort of explore other topics. And see kind of see what sticks. And this one stuck. It was picked up by a few customers and, and they’re really taking advantage of it. And then it’s kind of been sitting around for a while. So it occurs. It occurred to us that, you know, this is something that is probably pretty valuable that we’re not, we’re not putting in the hands of developers or it’s been kind of out there and available. So we’re kind of re-announcing it so that it’s really accessible and you can take advantage of it and help make improvements. So it’s a project as you all said that’s already deployed on GitHub. And it lives there with wiki documentation and an example solution, which is the one that I have open here that you can go ahead and download. So basically this way this works is text based searching for business applications and I’m going to show you and then we’ll dive into the details a bit. So here I have a sales order screen. It’s based on the example data database in the sort of ships by default with Servoy and I’m looking at orders, but also you can see related information about the customer and the order items and even the products that are there. So probably about five or six tables that are joined in here in the screen, a very typical kind of business application sort of screen. And then what I’m going to do is I’m going to type in some text into my search box here and we’ll look at the results. So I’m going to type in the word coffee and quickly you can see that all the orders that I click through as the results, they all have coffee as one of the one of the products that were ordered. I can type in additional word, let’s say Germany. Now you see that I have all of the orders which were shipped to Germany in the ship country here, but also they contain coffee as one of the products that was ordered. I want to narrow my search down further and let’s say that I’m interested in a particular sales rep, which is another table. You can see over here now I have Andrew Fuller as one of my sales reps. So only orders which were shipped to Germany containing coffee and also that were managed by that sales rep. It’s also works on string fragments so I would get the same results if I removed or a few letters from the name. So you can see that it’s matching on individual words or search tokens that I type. However, there’s more we can do operators. So let’s say for example that I’m interested in coffee again, I love coffee. And I want to find coffee which was ordered and I’m going to use an alias here with a colon after 1997 New Years. So now you can see on the order date column here that I’m showing all orders containing coffee every single one of these is going to have coffee in it which were ordered after 1997 New Years. I’m going to switch that to a between operator and we’ll take it to the end of the year. So now you can see that I have orders containing coffee and only in the year 1997 between February and December here. You can see the orders there. We can take it a step further you can see that I have a freight column here sometimes the freight is below $100 sometimes it’s above. So let’s add another search term freight again I’m going to use the alias for the column name and I’m going to do an operator of greater than 100. So now you can see coffee shipped in 1997 and freight is all above 100. So there’s other operators too. For example I could do coffee again, Germany again and you see that I have some customers here. I’m going to do minus quick and you can see that the quick stop customers that were there dropped out of the results you’ll put them back and they come back. So you can do an exclusion operator and you can also do an exact match. So I could do a quick and you see I get all the orders for the quick stop customer but if I do an exact match on quick with a plus quick I don’t get any results. If I had something that really amassed exactly on that column or that string fragment it would show up. There are more operators and there’s a couple more features but I think that’s enough to sort of show you kind of what’s quickly possible. I’ll take you through a bit of an explanation and then we can look under the hood at Servoy developer and see how you would implement this. So what the module does is really two things. Number one is it parses user input and sort of converts that into discrete search tokens or search terms. And then the second part is it gives developers an API to map sort of the input search criteria against their data model so that the module can automatically generate the input search criteria against their data model. So when you set up the map against your data model you create what we call search providers. You create a search object. Initialized against a specific data source. In this case it was the order stable. And then you can specify which data providers you want to be searchable. You may have noticed that in in the example I was doing we were searching not just columns that were immediately on the order stable like the order state and and such but also the related table of customer and the customer name. The related table of employee the sales rep name and then even two relations away to the product stable. And a little code snippet there shows you how easy it is to to create a search provider. As far as parsing input goes. It recognizes multiple tokens so token is something which is separated by white space. And you can escape tokens with quotes so this works just like an internet search if you if you type in two words it’ll search for something that has to match both of them. But if you quote it then it’s taken as one token where the space is literally interpreted. And the way it works is that all tokens must match any search provider. So what that really means is that that whatever you type in has to be has to be found but it will look across everything you’ve configured in your in your mapping. It feels very intuitive just like an internet search where if you type in a few words you expect to find all of those words but maybe in in unexpected locations. So another thing that is provided is aliasing for natural language and I.T.M. and doing explicit searches. You may have noticed that I typed in the word ordered colon and then the order date. That did that did first of all it allowed me to explicitly search on on the order date and when I do that it only that. Only that search provider of order date is is matched against the search token which was the actual date. Additionally you can use the alias not only to do an explicit search but also to help have more natural language in in those kinds of searches. So if you were to you know in this case the call name was ordered you know ordered date all one words wish together and I just made it ordered. But of course if I was doing a multilingual application I could I could put in I.T.M. messages instead. I guess it run time and that way I can have multi-lingual searching. So search providers can be made explicit only this is kind of a minor implementation detail but by default anything that you set up when you add a search provider. It will be searched so you might add you know ten search providers and and you type in one token and it’s going to look for that token across ten. Search providers but you could say I don’t want to let the user search for country unless they explicitly type it so then you could add more search providers which are really. And explicit search only and that’s a simple of bullying flag that you can set on the search provider level. You saw some of the operators that were supported so greater than greater than or equal to less than. I’ll send her equal to between are all supported. Also we showed the exclusion operator with the minus and the plus operator which is the exact match. And those work on on number fields and date fields and string fields. There are some other features as well. You can toggle case sensitivity on a on a search provider basis so by default it’s case insensitive but if you want to make a case sensitive search. You can you can just add that as a bullying flag. You can specify the date format by default it does a year month day that seems to be the only date format that the world can agree on that makes sense. Of course you might want to have your own locale date format as well and that’s easy to set. And then finally there’s something which is like a dynamic substitution of search token and what I mean by that is really the user might type one thing and then it will be. It’ll be substituted with something else and the reason we have this is you might have a valuous. Which has some word values and some some display values and the display value is what the user expects to match against and the stored values with the database holds it could be an integer and your typing text. So you can set up a substitution map and on a search provider by search provider basis and quickly you’re able to search these fields which are normally displayed through valuous. So let’s dive into a little bit behind the code. I’m going to switch over to Servoy developer and I lost my mouse. So I’m looking at my orders list here was the search field. It’s on action event is handled by a method called on search and pretty much what we do is there’s no search text user entered. I’m just loading all records of the found set. But step one is create this search object through the API and this is just a top level scope in the SFI search module. You can pass in the data sources a found set or a string data source. This works against in memory data sources as well. Then you want to set the search text. This is what the user has input. Then you want to set up your search providers. So in this example I set up these first four which go against the orders table directly. Then you see down here I have some related data providers to the customer and the employee. And then you can see, let me minimize this here to make more room. You can see down here I have all the way over to the product name. So when I type in a search token all of these search providers are searched. Basically I set that up as a string array but down here is where we actually call the API to add the search provider. And we can pass in the name of the data provider and some additional parameters if we want to. Order date we set the alias to be ordered instead of the actual column name which is order date. And we set that this was an implied search to false meaning you have to explicitly type in the alias. Otherwise this search provider won’t be searched. We did the same thing for freight and we don’t want to search freight. If you type in a string most of the time you’re not talking about an numeric field. So we set that as well to be an explicit search. So that’s all the work that we had to do is to set up the search providers, pass in the search text. And then we have the search object load the records on the found set. For fun I also print out the SQL that you would have had to come up with on your own after you were done parsing the search terms. So that’s pretty much it. There’s there’s a few other topics but you can get those from the wiki documentation. The project home is on GitHub. You can see there that we’re already in the second release. It’s worth pointing out to that there is comprehensive wiki documentation. Both about how the parsing happens. So there’s some examples of things that you type in how the parsed list of the operators. API documentation is completely documented in links there. So I think it’s pretty easy to get started. Also the very search example solution that we’re looking at is available if you go to the releases. Here you can see you can download the module as a Servoy export file. You can also download the example solution. Or if you prefer to run from source you can do a checkout from GitHub.