Many DNN users have had a similar experience with the limited results that DNN search offers particularly in the DNN 3.x versions. We are running DNN 3.0.13 and in addition to many other customizations we have recently retrofitted DNN search to dramatically improve results on our site.
Our primary issue had to do with the fact that we did have content but in many cases they were links to other content and while the link was descriptive the search indexer was unable to find it. The fix was rather straightforward, here is our modified version of AddIndexWords from the SearchDataStore.vb:
Private Sub AddIndexWords(ByVal IndexId As Integer, ByVal SearchItem As SearchItemInfo, ByVal Language As String)
Dim IndexWords As New Hashtable
Dim IndexPositions As New Hashtable
Dim setting As String
'Get the Settings for this Module
_settings = SearchDataStoreController.GetSearchSettings(SearchItem.ModuleId)
setting = GetSetting("MaxSearchWordLength")
If setting <> "" Then
maxWordLength = Integer.Parse(setting)
End If
setting = GetSetting("MinSearchWordLength")
If setting <> "" Then
minWordLength = Integer.Parse(setting)
End If
setting = GetSetting("SearchIncludeCommon")
If setting = "Y" Then
includeCommon = True
End If
setting = GetSetting("SearchIncludeNumeric")
If setting = "N" Then
includeNumbers = False
End If
Dim Content As String = CStr(IIf(SearchItem.Content Is Nothing, String.Empty, SearchItem.Content))
Dim Title As String = CStr(IIf(SearchItem.Title Is Nothing, String.Empty, SearchItem.Title))
Dim Desc As String = CStr(IIf(SearchItem.Description Is Nothing, String.Empty, SearchItem.Description))
' clean content
Content = HtmlUtils.Clean(Content, True)
Title = HtmlUtils.Clean(Title, True)
Desc = HtmlUtils.Clean(Desc, True)
' create a content string that includes the Title and Description
' copy the Title twice to place added weight on the words in the title
Content = String.format("{0} {1} {2} {3}", Title.ToLower, Title.ToLower, Desc.ToLower, Content.ToLower)
'' split content into words
Dim ContentWords() As String = Split(Content, " ")
' process each word
Dim intWord As Integer
Dim strWord As String
For Each strWord In ContentWords
If CanIndexWord(strWord, Language) Then
intWord = intWord + 1
If IndexWords.ContainsKey(strWord) = False Then
IndexWords.Add(strWord, 0)
IndexPositions.Add(strWord, 1)
End If
' track number of occurrences of word in content
IndexWords(strWord) = CType(IndexWords(strWord), Integer) + 1
' track positions of word in content
IndexPositions(strWord) = CType(IndexPositions(strWord), String) & "," & intWord.ToString
End If
Next
' get list of words ( non-common )
Dim Words As Hashtable = GetSearchWords() ' this could be cached
Dim WordId As Integer
'' iterate through each indexed word
Dim objWord As Object
For Each objWord In IndexWords.Keys
strWord = CType(objWord, String)
If Words.ContainsKey(strWord) Then
' word is in the DataStore
WordId = CType(Words(strWord), Integer)
Else
' add the word to the DataStore
WordId = Data.DataProvider.Instance().AddSearchWord(strWord)
Words.Add(strWord, WordId)
End If
' add the indexword
Dim SearchItemWordID As Integer = Data.DataProvider.Instance().AddSearchItemWord(IndexId, WordId, CType(IndexWords(strWord), Integer))
Data.DataProvider.Instance().AddSearchItemWordPosition(SearchItemWordID, CType(IndexPositions(strWord), String))
Next
End Sub
The modifications are highlighted in bold. Adding this improves index results for cases where the content may be limited but there are descriptive links to other content. In addition, the duplication provides added relevancy and helps in cases where the specific word may be competing with itself in another location but the version with the title should always take precedence.
Finally, GetSearchWords() has to be modified to accomindate a discreprency in the Hashtable, where it was indexed on the WordId but was queried on the Word. This improved our SearchWord table and prevents it now from growing out-of-control.