People are used to searching the internet and thanks to google, yahoo and bing everyone can find what they want within a few keystrokes and mouse clicks.
This means that people have been self trained from countless hours spent searching the web using these search engines. We developers can make use of this by providing the same style search in our applications.
Enter the Ivory .Net Language Implementation Kit. What is Ivory ? well Ivory is a developer kit for implementing languages on a .NET platform. You can write your own grammar class to be loaded into the ivory dll in the form of EBNF.
The grammar class basically contains the logic behind how we will provide a Google style syntax for our search engine. Using either c# or vb.net writing in the Extended Backus Naur Form (EBNF). Now i don’t profess to be an expert in EBNF, far from it in fact. I simply want to use the already built class found in this kit “FullTextSearchQueryConverter” found in Irony.Samples.FullTextSearch called SearchGrammer and insert it in between my search form and the database call.
The first thing your going to need is the kit, you must download it from here Irony Kit Once you have downloaded it and had a little test of your own you are likely ready to implement it.
Before you continue its in your interest to already have a search facility built that uses the full text search engine in sql server
Let’s beginPersonally I code in vb so I converted the SearchGrammer Class SearchGrammer
Add the aforementioned class to your project.
To integrate this into our search tool you need to locate the area just prior to where you called your Full text Search crunch against the DB.
I integrated mine in the following way.
1. Instantiate our Irony dll and load the grammer class
2. Run the search text through the engine to generate the fts clause
3. Verify there we no errors
4. Pass FTS to db call
Personally I instantiate the Irony class and load the search grammer when my main search class is instantiated.
From a topographical perspective this is the code needed to execute this type of search from anywhere in my application
1 2 3 |
Dim FT As New FTSearch Dim oDS As DataSet = Nothing oDS = FT.Items_Query(qry) |
Where qry is the search object containing amongst other things the search text from the input, and oDS is the returned results from the query
Line 1 instantiates the FT search class, this instantiates the irony dll and loads the searchgrammer like so.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Imports Irony.Parsing Public Class FTSearch Private _grammar As SearchGrammar Private _parser As Irony.Parsing.Parser Private _compilerContext As ParsingContext Private _parseTree As ParseTree Private priErrors As New StringBuilder Public Sub New() _grammar = New SearchGrammar _parser = New Parser(_grammar) _compilerContext = New ParsingContext(_parser) _parseTree = Nothing _parser.Context.SetOption(ParseOptions.TraceParser, True) 'Dim errors As StringSet = _compiler.Parser.GetErrors 'If (errors.Count > 0) Then ' Throw New Exception("SearchGrammar contains errors. Investigate using GrammarExplorer.\r\n" + errors.ToString()) 'End If End Sub |
To use this to generate the full text search query I can now perform the following from any part of the class
1 2 3 4 5 6 7 8 9 10 11 12 |
If Not String.IsNullOrEmpty(FriendlySrchString) Then Latest = False _parser.Parse(FriendlySrchString) _parseTree = _parser.Context.CurrentParseTree If Not CheckParseErrors() Then Return Nothing End If 'build the full text search condition ftString = SearchGrammar.ConvertQuery(_parseTree.Root) End If |
Where FriendlySearchString is the input string from your user, and ftstring contains the TFS search query we can pass over to which ever means you are using to build the query.
The last thing you will need is the CheckParseErrors() method
1 2 3 4 5 6 7 8 9 10 11 12 |
Private Function CheckParseErrors() As Boolean If _parseTree Is Nothing OrElse _parseTree.ParserMessages.Count = 0 Then Return True End If Dim errs As String = "Errors: " & vbCr & vbLf For Each err As Irony.Parsing.ParserMessage In _parseTree.ParserMessages errs = err.Location.ToString() & "Error: " & err.ToString() & "Parser State: " & err.ParserState.ToString() Next priErrors.AppendLine(errs) Return False End Function |
I posted a discussion within the irony forum that says a similar thing to this post found here
I hope this helped those who needed a how to on implementing irony as your google style FTS generator in your .NET apps.
Hi Andre — this is a great solution. I’ve implemented it in favor of my own (poor) parser and it’s bringing back much better results.
I have one case where it still causes a sql exception though – if a user uses single quotes to enclose a phrase rather than double quotes, it returns a “Null or empty full-text predicate.”
for example:
‘my name is’ Larry
any ideas?