Windows 10 UWP 20 of N: App search

  • 676
  • 0
  • UAP
  • 2021-04-30

How to make search in app is more powerful than you think?

今天要介紹得早在Windows 8 的時候就推出了Search功能!但基本上不會有特別的需求需要用使用該API,在一次偶然的情況下發現了該API的一些特性以及功能!

在一般的APP中大致都是提供Class內的某個字串型別的屬性或參數作為搜尋的目標,而在Windows提供原生Search方式給開發人員使用。

  1. Indexed Folder
  2. Content indexer

分為以上兩種!接下來分別介紹兩個search的功能


Inedxed folder

Indexed Folder 是特殊的資料夾,需建立在Local端 ( AppliocationData.Current.LocaFolder ) !當該資料夾被建立的時候系統會將該folder加入系統的Indexer的搜尋資料夾中,最簡單的範例就是Windows 10 內建的Settings app(UWP版本的控制台)

如上圖所示,就是Setting的搜尋功能

上圖所示就是Indexing options,可以發現系統有不少檔案處理方式都採用Indexed folder的機制。

然後來看一下如何使用Indexed folder八~

使用Indexed的搜尋模式需要在APP的 Local端建立一Folder

private const string IndexedFolderName = "Indexed";
//中間掠過~
private async Task InitializeIndexedSearchAsync()
        {
            var localFolder = ApplicationData.Current.LocalFolder;
            var indexedFolder = await localFolder.CreateFolderAsync(IndexedFolderName, CreationCollisionOption.OpenIfExists);
        }

這樣就是基礎的初始化Indexed folder的功能!只要建立該Indexed的Folder就可以簡單使用到索引搜尋的功能~

UWP有提供 Windows.Storage來進行檔案和資料夾的操作,而在該namespace下(Windows.Storage.Search)還有提供進行搜尋的功能相關功能。其中有個非常好用的Class- QueryOption!

QueryOption如同字面意思可以對搜尋做些額外的選項,簡單Sample如下

public asyn Task QueryFileAsync()
{
  var localFolder = ApplicationData.Current.LocalFolder;
  var queryOptions = new QueryOptions(CommonFileQuery.DefaultQuery, new string[] { ".txt" });
  var settings = await localFolder.CreateFileQueryWithOptions(queryOptions).GetFilesAsync();
}

使用QueryOption的constructor的時候就可以指定要使用Query的方式以及副檔名的指定!然後在搭配在StorageFolder的Query的相關API就可以做到File query的功能了!

接者有個可以輔助Indexed search的檔案結構 Application Content ( .appcontent-ms )主要格式是使用XML,簡單Sample如下

<?xml version="1.0" encoding="utf-8"?>
<IndexerSampleInformation>
  <Properties xmlns="http://schemas.microsoft.com/Search/2013/ApplicationContent">
    <Name>Sample 1</Name>
    <Keywords>
      <Keyword xml:lang="en-US">Sample 1 - keyword 1</Keyword>
      <Keyword>Sample 1 - keyword 2</Keyword>
    </Keywords>
    <Comment>Sample 1 comment</Comment>
    <AdditionalProperties>
      <Property Key="System.Title">Sample 1 Title</Property>
      <Property xml:lang="en-US" Key="System.Contact.EmailAddresses">
        <Value>bryan@contoso.com</Value>
        <Value>vincent@contoso.com</Value>
      </Property>
    </AdditionalProperties>
  </Properties>
  <IndexerSampleSpecificElement sc:IndexableContent="true" 
    xmlns:sc="http://schemas.microsoft.com/Search/2013/ApplicationContent">
    The text included here will be indexed, enabling full-text search.
  </IndexerSampleSpecificElement>
</IndexerSampleInformation>

這邊在Root node可以自訂名稱,並需要在Properties的部分給予namespace。如上Sample的XML中的IndexerSampleSpecificElement也是可以自訂的Node名稱,配合該Namespace以及IndexableContent = "true"就可以做到對該Node的Content進行Index的功能!

如果使用IndexerSampleSpecificElement這樣的寫法可以再額外設定內容格式!預設是Text的方式藉由ContentType的Attribute可以設定如下所示的類型。

  • application/hta
  • application/mac-binhex40
  • application/vnd.ms-xpsdocument
  • application/windows-appcontent+xml
  • application/x-compress
  • application/x-compressed
  • application/x-gzip
  • application/x-jtx+xps
  • application/x-latex
  • application/x-mplayer2
  • application/x-ms-wmz
  • application/x-stuffit
  • application/x-tar
  • application/x-zip-compressed
  • application/xml
  • audio/aiff
  • audio/basic
  • audio/mid
  • audio/midi
  • audio/mp3
  • audio/mpeg
  • audio/mpegurl
  • audio/mpg
  • audio/wav
  • audio/x-aiff
  • audio/x-mid
  • audio/x-midi
  • audio/x-mp3
  • audio/x-mpeg
  • audio/x-mpegurl
  • audio/x-mpg
  • audio/x-ms-wax
  • audio/x-ms-wma
  • audio/x-wav
  • image/bmp
  • image/gif
  • image/jpeg
  • image/pjpeg
  • image/png
  • image/vnd.ms-photo
  • image/x-emf
  • image/x-icon
  • image/x-png
  • image/x-wmf
  • midi/mid
  • model/vnd.dwfx+xps
  • model/vnd.easmx+xps
  • model/vnd.edrwx+xps
  • model/vnd.eprtx+xps
  • pkcs7-mime
  • text/css
  • text/html
  • text/plain
  • text/xml
  • video/avi
  • video/mpeg
  • video/mpg
  • video/msvideo
  • video/quicktime
  • video/x-mpeg
  • video/x-mpeg2a
  • video/x-ms-asf
  • video/x-ms-asf-plugin
  • video/x-ms-wm
  • video/x-ms-wmv
  • video/x-ms-wmx
  • video/x-ms-wvx
  • video/x-msvideo

接者把.appcontent-ms的檔案複製到Indexed folder就可以做到索引搜尋的功能了!如下C# code所示

private async Task InitializeIndexedSearchAsync()
        {
            var localFolder = ApplicationData.Current.LocalFolder;
            var indexedFolder = await localFolder.CreateFolderAsync("Indexed", CreationCollisionOption.OpenIfExists);
            var queryOptions = new QueryOptions(CommonFileQuery.DefaultQuery, new string[] { ".appcontent-ms" });
            var settingsFolder = await Package.Current.InstalledLocation.GetFolderAsync("Settings");
            var settings = await settingsFolder.CreateFileQueryWithOptions(queryOptions).GetFilesAsync();
            foreach (var file in settings)
            {
                await file.CopyAsync(indexedFolder, file.Name, NameCollisionOption.ReplaceExisting);
            }
        }

使用索引搜尋可以使用在比較簡單的檔案格式(文字)較為複雜的格式就得使用接者介紹的ContentIndexer了。

這邊有趣的是在appcontent-ms的XML的定義中的Keyword可以自訂語系!下方有個有趣的測試
<?xml version="1.0" encoding="utf-8" ?>
<AppSearchUWP>
  <Properties xmlns="http://schemas.microsoft.com/Search/2013/ApplicationContent">
    <Name>Color Setting</Name>
    <Keywords>
      <Keyword xml:lang="en-us">color</Keyword>
      <Keyword xml:lang="en-gb">colour</Keyword>
      <Keyword xml:lang="zh-tw">顏色</Keyword>
    </Keywords>
    <Comment>Choose the color of your app</Comment>

    <AdditionalProperties>
      <Property Key="System.Title">Title for color setting</Property>
    </AdditionalProperties>
  </Properties>
  <FullContentSearch_ZhTW xmlns:sc="http://schemas.microsoft.com/Search/2013/ApplicationContent" sc:IndexableContent="true">
    測試Abc
  </FullContentSearch_ZhTW>
</AppSearchUWP>

這邊有個 xml:lang="zh-tw",如果在語系及地區沒有設定在中文語系的區域就算輸入該Keyword是不會出現該資訊的!

 


ContentIndexer

使用ContentIndexer的Class使App提供Property bags( 屬性袋 ? )提供給系統做index並且可搜尋化!Property bags全都是metadata的資料形式敘述。Property bag可以包含任何屬性在shell property system!

那該怎樣選擇哪種搜尋方式呢?請看下表

功能 ContentIndexer Indexed folder
資料如何進入索引(index) app 主動推送資料,並且必須觀察確保indexing是成功建立的 app建立檔案在硬碟上,Indexer會主動管理indexing流程
App須提供的資料形式 property bag Any
索引優先程度控制 高優先序,並由app主要控制 無法控制索引建立優先序,可強制提高優先序藉由資料夾全域搜尋
重置後的行為 重新推送資料 系統自動重新建立

 

 

 

 

 

 

 

稍微解釋一下Shell property system,該System是在Windows的檔案敘述系統

 

 

 

 

 

***以上Code以及說明都有可能隨著Windows 10 的版本以及Visual Studio 2015版本有所調整!***

參考資料 MSDN, Searching private app data in windows 10

下次再分享Windows 10 的新技術拉~