Knowledgebase Home Page  >  SearchUnit
Search the Knowledge Base
How can I add my own content labels to the ResultItem template, and show my own data (eg. show number of instances of word in result)? (VB.NET)
https://keyoti.com/kb/Default.aspx?ToDo=view&questId=117&catId=54

Options

Print this page
Email this to a friend

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 instance

Dim da = New Keyoti.SearchEngine.DataAccess.XmlDataAccess

Dim documentRecords As ArrayList

Dim resultmap As OccurrenceMap

Sub InitializeMatchCounter()

'setup the index directory if necessary

Keyoti.SearchEngine.Configuration.xmlLocation = Me.SearchResult1.IndexDirectory

Dim searchTerm As String = Me.SearchResult1.QueryExpression.Split(" ")(0)

'open the data access

da.Open()

'retreive a map of the occurrences of searchTerm in all the documents in the index

resultmap = 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 Int32

Dim numberOfOccurrences As Integer

'find document in result map

Dim docRec As DocumentRecord

For Each docRec In documentRecords

'the URL we want

If (docRec.URI.ToString().Equals(uri)) Then

'the number of matches found in document

numberOfOccurrences = resultmap(docRec.DocumentID).Count

End If

Next docRec

 

Return numberOfOccurrences

End Function

4. 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 here

InitializeMatchCounter()

End Sub

 

Private Sub Page_Unload(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Unload

FinalizeMatchCounter()

End Sub

 

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

Dim lbl As Label

Dim resultData As Keyoti.SearchEngine.Search.ResultItem

resultData = 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 Then

lbl.Text = numberOfMatches & " matches found."

End If

End If

End 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


Related Questions:

Attachments: