Customizing the output of the SearchResult control is fairly simple, and done in a way like most templated controls. The ItemCreated event allows access to additional controls added to the template. Eg. to add a Label control to the ResultItemTemplate; 1. Under SearchResult, we add the label to the template; <ResultItemTemplate> <div class='SEResultItem'><table border="0"> <tr> <td class='SEResultItemLink' style='font-family:sans-serif, Verdana, Arial, Helvetica; font-size:10pt; '><A href="<%# Container.Uri %>"><%# Container.Title %></A></td> </tr> <tr> <td class='SEResultItemSummary' style='font-family:sans-serif, Verdana, Arial, Helvetica; font-size:9pt; '><%# Container.Summary%></td> </tr> <tr> <td class='SEResultItemURL' style='font-family:sans-serif, Verdana, Arial, Helvetica; font-size:8pt; color: green; '><%# Container.Uri %></td> </tr> </table> <asp:Label Runat="server" ID="matchNumLabel"></asp:Label> </div> <br> </ResultItemTemplate> 2. And then to programmatically access the label at runtime, hook into the ItemCreated event; Private Sub SearchResult1_ItemCreated(ByVal sender As Object, ByVal e As Keyoti.SearchEngine.Web.SearchResultItemEventArgs) Handles SearchResult1.ItemCreated If TypeOf e.Item Is Keyoti.SearchEngine.Web.ResultItem Then 'only interested in ResultItems Dim lbl As Label Dim resultData As Keyoti.SearchEngine.Search.ResultItem 'the underlying ResultItem is accessable like this if req.d resultData = CType(e.Data, Keyoti.SearchEngine.Search.ResultItem) lbl = CType(e.Item.FindControl("matchNumLabel"), Label) If Not lbl Is Nothing Then lbl.Text = "hello" End If End If End Sub Now let's take it a step further and show information about the search result. Consider the requirement that the number of matches of the first (for simplicity) search term be shown next to the result. 3. Add some methods that can do the work of finding the number of occurrences of a term 'create a data access instanceDim da = New Keyoti.SearchEngine.DataAccess.XmlDataAccessDim documentRecords As ArrayListDim resultmap As OccurrenceMapSub InitializeMatchCounter()'setup the index directory if necessaryKeyoti.SearchEngine.Configuration.xmlLocation = Me.SearchResult1.IndexDirectoryDim searchTerm As String = Me.SearchResult1.QueryExpression.Split(" ")(0)'open the data accessda.Open() 'retreive a map of the occurrences of searchTerm in all the documents in the indexresultmap = da.GetMatchingDocumentsAndOccurrencesForWord(searchTerm, New ArrayList, New Hashtable, New Keyoti.SearchEngine.Search.SearchOptions)'the map contains document IDs, but we want the actual DocumentRecords for those IDs so we can get the URL of the doc.documentRecords = da.GetDocuments( New ArrayList(resultmap.DocumentIDs))End Sub'important to call this at the end Sub FinalizeMatchCounter()da.Close() End Sub 'returns the number of matches for searchTerm in the document specified by uri Function FindNumberOfMatches(ByVal uri As String) As Int32Dim numberOfOccurrences As Integer'find document in result mapDim docRec As DocumentRecordFor Each docRec In documentRecords'the URL we wantIf (docRec.URI.ToString().Equals(uri)) Then'the number of matches found in documentnumberOfOccurrences = resultmap(docRec.DocumentID).Count End IfNext docRec Return numberOfOccurrencesEnd Function4. Call these as required; Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load'Put user code to initialize the page hereInitializeMatchCounter() End Sub Private Sub Page_Unload(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.UnloadFinalizeMatchCounter() End Sub Private Sub SearchResult1_ItemCreated(ByVal sender As Object, ByVal e As Keyoti.SearchEngine.Web.SearchResultItemEventArgs) Handles SearchResult1.ItemCreatedIf TypeOf e.Item Is Keyoti.SearchEngine.Web.ResultItem ThenDim lbl As LabelDim resultData As Keyoti.SearchEngine.Search.ResultItemresultData = CType(e.Data, Keyoti.SearchEngine.Search.ResultItem)Dim numberOfMatches = Me.FindNumberOfMatches(resultData.URIString)lbl = CType(e.Item.FindControl("matchNumLabel"), Label)If Not lbl Is Nothing Thenlbl.Text = numberOfMatches & " matches found." End IfEnd IfEnd Sub Caveats about this example: although there are no draw back to accessing the label in the ItemCreated event, there are draw backs to the way we've calculated the number of matches; 1. There is additional workload (although not a particularly large percentage more) 2. Only the number of matches for the first word were found - if this is not ok, you would need to do multiple calls to resultmap = da.GetMatchingDocumentsAndOccurrencesForWord(searchTerm, New ArrayList, New Hashtable, New Keyoti.SearchEngine.Search.SearchOptions)
one for each word. And also track each resultmap in the FindNumberOfMatches method. 3. Only exact hits for the word are counted, lemmas (variations) are not, if this is required, you can pass the lemmas as a list of strings in the 2nd argument in GetMatchingDocumentsAndOccurrencesForWord. You can get a list from the Keyoti.SearchEngine.DataAccess.IDataAccess.GetWordVariations method in XmlDataAccess. --If you'd like to discuss these issues, please email us. The complete code-behind file for this page is attached - please ask any questions on the forum or email support@keyoti.com |