Instant Search and Your Inner Developer

One of the great new features in Outlook 12, as anyone who has used it can vouch, is Instant Search.  Michael’s blog has a lot more details about the UI exposure of this feature and the inner workings behind it, so if you aren’t familiar with the feature, check here first.  Done?  OK, on to programmability then!  Many Outlook developers know the pain of trying to locate an item in a folder with thousands of messages.  In the past, you were restricted to using slow operators such as “LIKE” or “=” in your restriction or advanced search, which was nearly always slow.

Since Outlook has added a fast search feature, it was only fair that developers be able to party on this code as well.  As such, we have exposed two new operators available through the DASL query language which allow you to use the content indexer-based search (the Instant Search feature).  If you were previously using the JET-based query language, sorry these keywords only work in DASL.  You will need to look into converting your queries over to DASL to take advantage of the new search.

These two new keywords, CI_STARTSWITH and CI_PHRASEMATCH are simple and powerful extensions to DASL.  You can almost just replace your LIKE or = operator with the new keyword and see fast results immediately.  For instance, let’s say you were filtering an inbox for items where the subject contained the word “security”.  In the past, your code might have looked like this:

Sub SearchForSecurity()
Dim inbox As Folder
Set inbox = Session.GetDefaultFolder(olFolderInbox)

Dim filter As String
filter = "@SQL=(" & Chr(34) & "urn:schemas:httpmail:subject" & _
Chr(34) & " LIKE '%security%')"

Dim matchingItems As items
Set matchingItems = inbox.items.Restrict(filter)

MsgBox "There are " & matchingItems.Count & " items that matched 'security'"
End Sub

Pretty simple query, but the results could take a considerable amount of time to return depending on how many items where in the folder.  Now with a slight tweak to the syntax, you can use the content indexer search and get the results much faster:

Sub SearchForSecurity()
Dim inbox As Folder
Set inbox = Session.GetDefaultFolder(olFolderInbox)

Dim filter As String
filter = "@SQL=(" & Chr(34) & "urn:schemas:httpmail:subject" & _
Chr(34) & " CI_PHRASEMATCH 'security')"

Dim matchingItems As items
Set matchingItems = inbox.items.Restrict(filter)

MsgBox "There are " & matchingItems.Count & " items that matched 'security'"
End Sub

The difference between using CI_STARTSWITH and CI_PHRASEMATCH should be pretty clear from their names, but I’ll go ahead and explain anyway.

  • CI_STARTSWITH uses prefix matching to identify matching words from the search field.  For instance, if you used CI_STARTSWITH ‘secur’ in the code above, you would find items with “security” and “secure” in the subject.
  • CI_PHRASEMATCH matches based on the phrase instead of prefix matching.  If you used CI_PHRASEMATCH ‘secur’ you would only find items that had the string “secur” as a word in the subject (since “secur” isn’t a word, I didn’t find anything in my inbox).  CI_PHRASEMATCH looks for a complete matching phrase, so if you were looking for “Security Risks” you could use CI_PHRASEMATCH ‘security risks’ and return only items that have those two words together.

One difference from the LIKE operator to be aware of is that neither of the new keywords support postfix matching.  When using the LIKE keyword, you could use “LIKE ‘%ity’”, which would find “security” and “possibility” among other terms.  A search like this isn’t possible using the new content indexer, which only supports prefix and phrase matching.  However, despite this limitation both of these search terms are powerful operators for using Instant Search in Outlook.

But wait, there’s even more!

Let’s say that instead of your add-in trying to retrieve these results for some internal process, it needed to display the results to the user.  Outlook 12 has made this easier through a new Search method on the Explorer class.  By calling Search, you can specify the query syntax in the same fashion the user would type into Outlook’s find pane, and present the user with an explorer view showing the results.  For instance, the following code snippet will search the user’s inbox for e-mail containing the word security in the subject, and show any matching items to the user:

Sub ShowSearchUI()
' Get the inbox
Dim inbox As Folder
Set inbox = Session.GetDefaultFolder(olFolderInbox)

' Create a new explorer window
Dim exp As Explorer
Set exp = Application.Explorers.Add(inbox, _
olFolderDisplayNoNavigation)

' Search for subject:security in the current folder only
exp.Search "subject:security", False
' Display the results
exp.Display
End Sub

Presto, the user sees the instant search results in a new window.  They also get to see the search query so they can repeat the query again in the future or refine it to better find the items they were looking for.

In conclusion, Outlook 12’s new “Instant Search” feature is great for end users and developers alike.  Building a great solution that can rely on the new Outlook search functionality in this manner should be a breeze for the experienced Outlook developer.