65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (1投票)

2016 年 7 月 5 日

CPOL

6分钟阅读

viewsIcon

34454

隆重推出适用于 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.dlldtSearchEngine_uwp_Win32.dll 之上提供了一个托管 API 包装器,其 API 与 .NET API 非常相似。我像引用任何其他 DLL 一样将托管库添加到我的项目中作为引用,并将本地 DLL 添加到我的项目中,并将其“生成操作”属性设置为“内容”,以便它会随着我的应用程序一起部署。

图 1 - 我的应用程序中的本地库引用

我想构建一个可搜索的著名美国文件索引,以便在那些社交媒体讨论中,当人们喜欢引用国家法律时,我可以非常快速地引用它们。我首先从美国国家档案馆在线复制这些著名文件的部分转录,并在项目中的 Docs 文件夹中生成一些文本文件或 Word 文档。与本地 DLL 一样,我将每个文档标记为“内容”和“如果更新则复制”。这样,它们就会被复制到 APPX 中,并在应用程序部署时可在应用程序文件夹中找到。这一点很重要,因为我想能够显示整个文档并突出显示搜索词。

图 2 - 文档内容配置

索引我们的文档

在任何搜索操作发生之前,我需要 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 引擎提供了一个词汇表功能,可以为您正在查找的术语提供快速的前缀或智能感知行为。在我的例子中,我将在页面上创建一个搜索文本框,并在文本框中文本更改时提供前缀查找。

图 3 - UWP 应用程序中从文本框进行的前缀搜索

我可以通过配置 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);
    }
  }
}

此代码使用 BeforeHitAfterHit 属性中的语法高亮显示 HTML 标记以及 OutputFormat 作为 HTML 来设置 FileConverter。调用 Execute() 后,FileConverterOutputString 属性将包含文档的 HTML 视图,其中包含标记的命中,以便使用 webView.NavigateToString 在 WebView 控件中显示。

图 4 - 带高亮显示的搜索结果

摘要

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(EC2 & EBS)
使用 dtSearch 和 AWS Aurora 进行全文搜索

© . All rights reserved.