在您的 Windows 10 通用 (UWP) 应用程序中嵌入搜索引擎





2.00/5 (1投票)
隆重推出适用于 UWP 的 dtSearch 引擎。此作者还提供了适用于 Android 的 dtSearch 引擎(请参阅文章获取链接)以及使用 dtSearch 引擎的高级分面搜索。
我花了一些时间研究 dtSearch 库,为我网上的多个应用程序和我的Android 设备添加搜索功能。在本文中,我将向您展示如何为 Windows 10 通用应用程序添加简单的全文本文档搜索功能。
配置
首先,我获取 dtSearch 库和本地 DLL 副本以添加到我的项目中。适用于 UWP 的 dtSearch 引擎有两个组件:
dtSearchEngine_uwp_Win32.dll (C/C++ API)
dtSearchUwpApi.dll (适用于 C#、Visual Basic 或 C++ 的托管代码 API)
dtSearchUwpApi.dll 在 dtSearchEngine_uwp_Win32.dll 之上提供了一个托管 API 包装器,其 API 与 .NET API 非常相似。我像引用任何其他 DLL 一样将托管库添加到我的项目中作为引用,并将本地 DLL 添加到我的项目中,并将其“生成操作”属性设置为“内容”,以便它会随着我的应用程序一起部署。
我想构建一个可搜索的著名美国文件索引,以便在那些社交媒体讨论中,当人们喜欢引用国家法律时,我可以非常快速地引用它们。我首先从美国国家档案馆在线复制这些著名文件的部分转录,并在项目中的 Docs 文件夹中生成一些文本文件或 Word 文档。与本地 DLL 一样,我将每个文档标记为“内容”和“如果更新则复制”。这样,它们就会被复制到 APPX 中,并在应用程序部署时可在应用程序文件夹中找到。这一点很重要,因为我想能够显示整个文档并突出显示搜索词。
索引我们的文档
在任何搜索操作发生之前,我需要 dtSearch 来构建我的文档索引。对于这个演示,我将在应用程序中添加索引操作。如果我的用户想从正在运行的应用程序中向索引添加文档,那么他们将需要在添加文档后更新索引。要实现这一点,我添加一个“生成索引”按钮,该按钮会将 Docs 文件夹的内容添加到索引中。应用程序可以从标准的 ApplicationData 和 Package 对象推断出 Docs 和 Index 文件夹的位置。由于索引文件夹是读/写的,所以它必须放在 ApplicationData 对象下的 LocalFolder 中,而 Docs 文件夹将放在 Package 对象下的 InstalledLocation 文件夹中。
private String indexPath;
private String docFolder;
public MainPage()
{
this.InitializeComponent();
indexPath = Windows.Storage.ApplicationData.Current.LocalFolder.Path + Path.DirectorySeparatorChar + "index";
docFolder = Windows.ApplicationModel.Package.Current.InstalledLocation.Path + Path.DirectorySeparatorChar + "Docs";
}
有了这些位置,我现在可以将 buildIndexButton_Click
事件连接到 dtSearch IndexJob 操作。事件处理程序方法首先定义 dtSearch 能够构建索引所需的其他文件夹位置选项。
private void buildIndexButton_Click(object sender, RoutedEventArgs e)
{
// Setting Options.TempFileDir and Options.HomeDir is required to tell the dtSearch Engine
// where to find configuration files and where to store temp data.
Options options = new Options();
options.TempFileDir = Windows.Storage.ApplicationData.Current.TemporaryFolder.Path;
options.HomeDir = Windows.ApplicationModel.Package.Current.InstalledLocation.Path;
options.Save();
用几行代码即可创建我的 Docs 文件夹中重要文档的搜索索引,然后
// Build the index
dtSearch.Engine.IndexJob indexJob = new IndexJob();
indexJob.IndexPath = indexPath;
indexJob.ActionCreate = true;
indexJob.ActionAdd = true;
indexJob.FoldersToIndex.Add(docFolder);
indexJob.IncludeFilters.Add("*.txt");
indexJob.IncludeFilters.Add("*.doc");
indexJob.Execute();
有了这八行代码,我就创建了一个构建索引的作业,并指示了其输出的写入位置。我告诉它在索引不存在时创建索引,并向其中添加记录。FoldersToIndex
集合包含一个文件夹,docFolder,我在该类的构造函数中捕获了它,并将其分配给了 Docs 文件夹的部署位置。IncludeFilters
集合指定了要索引的文档的文件扩展名。最后,Execute()
调用构建索引。
前缀搜索
dtSearch 引擎提供了一个词汇表功能,可以为您正在查找的术语提供快速的前缀或智能感知行为。在我的例子中,我将在页面上创建一个搜索文本框,并在文本框中文本更改时提供前缀查找。
我可以通过配置 Search Request 文本框的 TextChanged
事件处理程序,在 ListBox 中提供这些简单的结果。列出搜索结果只需要几行代码。
private void searchRequest_TextChanged(object sender, TextChangedEventArgs e)
{
if (wordListBuilder == null)
{
wordListBuilder = new WordListBuilder();
wordListBuilder.OpenIndex(indexPath);
}
wordListBuilder.ListWords(searchRequest.Text, 5);
fileList.Items.Clear();
for (int i = 0; i < wordListBuilder.Count; ++i)
{
fileList.Items.Add(wordListBuilder.GetNthWord(i) +
" " + wordListBuilder.GetNthWordCount(i));
}
}
在此代码中,我在类级别构造一个 wordListBuilder
对象,该对象引用磁盘上的索引,因此我不必在每次按键时重新初始化它。ListWords
方法从索引中获取搜索词之前和之后的五个词。在清除 fileList ListBox 后,我将找到的词和每个词的出现次数填充到 ListBox 中。
搜索文件和报告结果
搜索后,我想能够显示文档列表,以便我找到该词的使用情况,并在社交媒体上赢得我的论点。要搜索文本框中的请求,我创建一个搜索按钮单击事件处理程序来执行搜索。
private dtSearch.Engine.SearchResults searchResults;
private void searchButton_Click(object sender, RoutedEventArgs e)
{
fileList.Items.Clear();
dtSearch.Engine.SearchJob searchJob = new SearchJob();
if (searchResults != null)
{
searchResults.Dispose();
searchResults = null;
}
searchResults = new SearchResults();
searchJob.IndexesToSearch.Add(indexPath);
searchJob.Request = searchRequest.Text;
searchJob.MaxFilesToRetrieve = 10;
searchJob.AutoStopLimit = 100;
searchJob.TimeoutSeconds = 3;
searchJob.Execute(searchResults);
此代码清除可能包含建议词或先前搜索结果的 ListBox。然后它创建一个 SearchJob
并初始化 SearchResults
以接收搜索引擎的输出。它将 IndexesToSearch
集合指向先前创建的 indexPath
,并定义了一些合理的限制,例如最大文件数、搜索后停止的文件数以及搜索超时秒数。调用 Execute()
方法会执行搜索,并将 SearchResults
对象填充搜索结果。
然后,我可以使用标准的 for 循环遍历 SearchResults
,并将这些值放入用户界面中的 ListBox 中。
for (int i = 0; i < searchResults.Count; ++i)
{
SearchResultsItem item = new SearchResultsItem();
if (searchResults.GetNthDoc(i, item))
{
string name = item.Filename;
if (name.StartsWith(docFolder))
{
name = name.Substring(docFolder.Length + 1);
}
fileList.Items.Add(name);
}
}
此块中的“If”语句检查是否可以从索引中读取相关的文档记录,除非索引意外变得不可访问,否则这应该始终是这种情况。
显示内容
接下来,我非常想显示文档中搜索词的上下文。我在 ListBox 的 SelectionChanged
事件上创建一个最终事件处理程序,并使用 dtSearch FileConverter
输出一些格式良好的 HTML,其中包含应用于词语的上下文高亮显示。我在界面中添加了一个 WebView,并使用它来显示我高亮显示的输出。
private void fileList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
int iItem = fileList.SelectedIndex;
using (FileConverter fc = new FileConverter())
{
if (fc.SetInputItem(searchResults, iItem))
{
fc.BeforeHit = "<b style='background-color: yellow'>";
fc.AfterHit = "</b>";
fc.OutputToString = true;
fc.OutputFormat = OutputFormat.itHTML;
fc.Execute();
webView.NavigateToString(fc.OutputString);
}
}
}
此代码使用 BeforeHit
和 AfterHit
属性中的语法高亮显示 HTML 标记以及 OutputFormat
作为 HTML 来设置 FileConverter
。调用 Execute()
后,FileConverter
的 OutputString
属性将包含文档的 HTML 视图,其中包含标记的命中,以便使用 webView.NavigateToString
在 WebView 控件中显示。
摘要
dtSearch 使我能够轻松地为该项目添加丰富的搜索功能。凭借跨字段搜索和分面搜索等其他功能,我的下一个项目有很多选择。dtSearch 演进到支持 UWP 及其其他支持的框架,巩固了它在我开发工具箱中作为首选搜索库的地位。
更多关于 dtSearch
dtSearch.com
口袋里的搜索引擎 – 介绍 Android 上的 dtSearch
云端疾速源代码搜索
使用 Azure 文件、RemoteApp 和 dtSearch,从任何计算机或设备跨越 PB 级数据的各种数据类型进行安全即时搜索
使用 dtSearch 引擎进行 Windows Azure SQL 数据库开发
使用 dtSearch 进行分面搜索 - 不是普通的搜索过滤器
使用 dtSearch® ASP.NET Core WebDemo 示例应用程序极速提升您的搜索体验
在您的 Windows 10 通用 (UWP) 应用程序中嵌入搜索引擎
使用 dtSearch Engine DataSource API 索引 SharePoint 网站集
使用 dtSearch® ASP.NET Core WebDemo 示例应用程序
在 AWS 上使用 dtSearch(
使用 dtSearch 和 AWS Aurora 进行全文搜索