There are many articles on the internet about querying Index Server using MSIDXS but few concerning IXSSO in .Net. It is my hope that this article will help more developers to return to the more efficient IXSSO when developing Index Server solutions in the .Net framework. The complete code with explanation is available in a .zip file by clicking here. The coding represented here won't be to the liking of all, but it will get you started. It is presumed that you understand .Net controls and Index Server commands.
Let's make a user interface. We will create a GUI that will allow the users to select areas of the website they are interested in, and to ignore other areas. We also want to ensure that the user isn't overwhelmed with the number of returns on each page so we will create a pageable datagrid to house the results of their query.
Figure 1. User Interface on Page Load
The code for the controls in Figure 1 is as follows:
<asp:textbox
id="txtSearch"
Runat="Server"
Columns="40"></asp:textbox>
<asp:button
id="Button1"
onClick="doSubmit" Runat="Server"
Text="Search!"></asp:button>
<h4>Optional
- Select areas to be searched</h4>
<asp:CheckBoxList
ID="chkListFolders"
Runat="Server"
RepeatColumns="4"
RepeatDirection="Vertical"></asp:CheckBoxList>
<hr>
Notice that the check box is not populated on the
client-side. The name and values of the folders represented in the check box are
bound on the code behind page in the Page_Load Subroutine. In addition to the
visible controls in Figure 1, we also want to include a label and a datagrid.
Now, we will move on to create the code behind
page that contains the functionality for the query and all the controls. We'll
start from the top and work our way down.
Imports System
Imports System.Data
Imports System.Data.Oledb '
for DA and DS
Imports System.Web.UI
Imports System.Web.UI.WebControls
' for Datagrid
Imports System.Text ' for stringbuilder
Public Class IndexControls_main
Inherits Page
Protected WithEvents lblResults
As Label
Protected WithEvents
chkListFolders As CheckBoxList
Protected WithEvents txtSearch
As TextBox
Protected WithEvents dgResults
As DataGrid
The namespaces must be imported to provide
definitions and framework for the objects created in the code. After the
imports, we create a class called "IndexControls_main" which we referred to on
the top of the IndexServer_dotNet.aspx page. The class inherits the page, and on
that page are four web controls which we will protect.
' PRE-SELECT ALL CHECK BOXES
' The check boxes control which folders are searched in the
' the query. For convenience, all boxes are pre-checked and
' if the user wants to narrow their search, they may uncheck
them.
Dim itmFold
As ListItem
For each
itmFold in chkListFolders.Items
itmFold.selected=true
Next
Else
' do nothing - check boxes will retain their
' checked or unchecked values
End If
End Sub
On Page_Load, if the page has not
been posted back (default page view when user loads the page for the very first
time), we bind an arraylist to a checkbox list. The first value is the name to
be displayed beside the check box, and the second value is the actual name of
the folder that will be searched. Next, we use a FOR loop to loop through all
the items in the array in order to provide pre-checked check boxes. This way,
the users get the widest possible scope of returns if they don't want to fuss
check boxes.
Sub doSubmit(ByVal
s As Object, ByVal
e As EventArgs)
' SEARCH BUTTON EXECUTES THIS SUB
' Set the datagrid to page zero so when the search
' query is changed, new results start at page zero
dgResults.CurrentPageIndex = 0
getResults()
End Sub
The search button shown in Figure 1 executes the
doSubmit routine. While the routine may not seem necessary at first glance, it
becomes an extremely efficient way of dealing with new searches that are
executed after another dataset has been opened and paged. The datagrid is set to
page zero so that new searches begin where they are supposed to, not at whatever
page you were at on your previous search. The routine also triggers getResults.
Sub
getResults()
' triggered by doSubmit and
getResults_PageIndexChanged
Dim SearchString
As String = txtSearch.Text
Dim DA As
New OleDbDataAdapter
Dim DS As
New DataSet("IndexServerResults") ' give the dataset a name
Dim Q As
Object = Server.CreateObject("ixsso.Query")
Dim Util
As Object = Server.CreateObject("ixsso.Util")
This creates a few necessary objects. In object DS, we give a name to the
dataset. We could just as well have called it "Thingmabob" as the name is just a
name, but once made it is treated as the name of a table holding the dataset.
The query object and the utility are made as they always have been in classic
.asp.
Dim strbldSearch As New
StringBuilder(SearchString)
' EXLUDE FOLDERS AND FILES FROM SEARCH
' Anything that you don't want people to find in their
' search results should go here.
strbldSearch.Append(" and not #vpath = *\_vti_cnf*")
strbldSearch.Append(" and not #vpath = *\_mmServerScripts*")
strbldSearch.Append(" and not #vpath = *\YourFolderName*")
strbldSearch.Append(" and not #vpath = *\images*")
strbldSearch.Append(" and not #filename *.inc")
strbldSearch.Append(" and not #filename *.vb")
Q.Query = strbldSearch.ToString()
Q.Catalog = "YourCatalogName" ' name of
your IndexServer Catalog
Q.SortBy = "rank[a]" ' a-ascending,
d-descending
Q.Columns = "Rank, DocTitle, vpath, filename"
Q.MaxRecords = 250
I have chosen to use StringBuilder to add parameters to the query. We begin by
excluding certain files and folders from the scope of our search. The query (Q)
also allows you to select columns from the Index Server engine and to limit the
number of possible returns given to the user. Sure, you may have 10,000 files
referencing amylase, but will they page through so large a record set? Better to
keep the number low and the quality high. More than 500 is generally taxing on
both the system's memory and the user's patience.
' INCLUDE FOLDERS IN SEARCH
' (1) Always include root directory, but not sub folders
Util.AddScopeToQuery(Q, "/", "shallow")
' (2) Include folders selected in check box list AND their
' their sub folders. See sub Page_Load check list array
Dim itmFolder
As ListItem
For each itmFolder in
chkListFolders.Items
If
itmFolder.Selected Then
Util.AddScopeToQuery(Q, "/" & itmFolder.Value, "deep")
End If
Next
In this sample, we always wish to include the homepage in the scope of the
search. This is performed by selecting the base of the website "/" and using
"shallow" to indicate that we do not include sub folders in this one parameter.
Since we are also allowing the users to use a check box list to select which
areas of the website they wish to search, we use a FOR loop to loop through the
selected items in the check box list and add these to the parameters of the
search. We use "deep" to indicate that we wish to have sub folders included in
these instances.
Try
DA.Fill(DS,
Q.CreateRecordset("nonsequential"), "IndexServerResults")
Dim intRowCount
AS Integer
intRowCount =
DS.Tables("IndexServerResults").Rows.Count
lblResults.Text = "There are " &
intRowCount & " records."
dgResults.DataSource = DS
dgResults.DataBind()
Q = Nothing
util = Nothing
Catch exc
As Exception
lblResults.Text = "There were no
search results. Please rephrase your query"
'lblResults.Text
= exc.Message
End Try
End Sub
It's time to execute the code! We use a TRY statement to catch exceptions and
assist with debugging. We populate the data adapter with the dataset, count the
rows, and bind the results to the datagrid. If there is an exception, we may
have the exception message written out or on production, tell us that there are
no available results. All that is left now is the routine for paging:
'
handles dataset paging
Sub getResults_PageIndexChanged(ByVal
sender As Object, ByVal
e As DataGridPageChangedEventArgs)
dgResults.CurrentPageIndex = e.NewPageIndex
getResults()
End Sub
End Class
The dataset paging performs exactly like any other datagrid event. The final
results should look like Figure 2:
Figure 2. Dataset bound to pageable datagrid
In Summary, IXSSO has always
offered an effective means of querying Index Server. By adapting this time
tested technology to the new ways of .Net, we will help users to find what they
need, quickly, on our websites. We also provide them with the option of
narrowing their search, and reward them with the convenience of pageable
results.
Code Download
You can download the code in zip file format from here: indexserver_dotnet.zip (3.1 KB).