使用 Azure 搜尋服務和搜尋數據 Xamarin.Forms

Download Sample 下載範例

Azure 搜尋服務是雲端服務,可為上傳的數據提供索引編製和查詢功能。 這會移除基礎結構需求和搜尋演算法的複雜性,傳統上與在應用程式中實作搜尋功能相關聯。 本文示範如何使用 Microsoft Azure 搜尋服務連結庫將 Azure 搜尋服務整合到 Xamarin.Forms 應用程式中。

概觀

數據會以索引和檔的形式儲存在 Azure 搜尋服務中。 索引是 Azure 搜尋服務 可以搜尋的數據存放區,在概念上類似於資料庫數據表。 檔是索引中可搜尋數據的單一單位,在概念上類似於資料庫數據列。 上傳檔並將搜尋查詢提交至 Azure 搜尋服務時,會向搜尋服務中的特定索引提出要求。

對 Azure 搜尋服務提出的每個要求都必須包含服務的名稱和 API 金鑰。 API 金鑰有兩種類型:

  • 管理員 金鑰會授與所有作業的完整許可權。 這包括管理服務、建立和刪除索引,以及數據源。
  • 查詢密鑰 會授與索引和檔的唯讀存取權,而且應該由發出搜尋要求的應用程式使用。

對 Azure 搜尋服務最常見的要求是執行查詢。 有兩種類型的查詢可以提交:

  • 搜尋查詢會搜尋索引中所有可搜尋欄位的一或多個專案。 搜尋查詢是使用簡化的語法或 Lucene 查詢語法所建置。 如需詳細資訊,請參閱 Azure 搜尋服務中的簡單查詢語法,以及 Azure 搜尋服務中的 Lucene 查詢語法。
  • 篩選查詢會評估索引中所有可篩選欄位的布爾表達式。 篩選查詢是使用 OData 篩選語言的子集所建置。 如需詳細資訊,請參閱 Azure 搜尋服務的 OData 運算式語法。

搜尋查詢和篩選查詢可以分開或一起使用。 一起使用時,篩選查詢會先套用至整個索引,然後在篩選查詢的結果上執行搜尋查詢。

Azure 搜尋服務也支持根據搜尋輸入擷取建議。 如需詳細資訊,請參閱 建議查詢

注意

如果您沒有 Azure 訂用帳戶,請在開始之前建立 免費帳戶

設定

將 Azure 搜尋服務整合到 Xamarin.Forms 應用程式的程式如下:

  1. 建立 Azure 搜尋服務。 如需詳細資訊,請參閱使用 Azure 入口網站建立 Azure 搜尋服務。
  2. 從 Xamarin.Forms 解決方案可攜式類別庫 (PCL) 中移除 Silverlight 作為目標架構。 這可以藉由將 PCL 配置檔變更為任何支援跨平台開發的配置檔來完成,但不支援 Silverlight,例如設定檔 151 或設定檔 92。
  3. Microsoft Azure 搜尋服務連結庫 NuGet 套件新增至解決方案中的 Xamarin.Forms PCL 專案。

執行這些步驟之後,Microsoft 搜尋 連結庫 API 可用來管理搜尋索引和數據源、上傳和管理檔,以及執行查詢。

建立 Azure 搜尋服務索引

必須定義索引架構,以對應至要搜尋之數據的結構。 這可以在 Azure 入口網站中完成,或使用 類別以程式設計方式 SearchServiceClient 完成。 此類別會管理 Azure 搜尋服務的連線,並可用來建立索引。 下列程式代碼範例示範如何建立這個類別的實例:

var searchClient =
  new SearchServiceClient(Constants.SearchServiceName, new SearchCredentials(Constants.AdminApiKey));

SearchServiceClient構函式多載會採用搜尋服務名稱和SearchCredentials物件做為自變數,SearchCredentials而對象會包裝 Azure 搜尋服務 的管理密鑰。 需要系統 管理金鑰 才能建立索引。

注意

應用程式應該使用單 SearchServiceClient 一實例,以避免開啟太多 Azure 搜尋服務的連線。

物件會 Index 定義索引,如下列程式代碼範例所示:

static void CreateSearchIndex()
{
  var index = new Index()
  {
    Name = Constants.Index,
    Fields = new[]
    {
      new Field("id", DataType.String) { IsKey = true, IsRetrievable = true },
      new Field("name", DataType.String) { IsRetrievable = true, IsFilterable = true, IsSortable = true, IsSearchable = true },
      new Field("location", DataType.String) { IsRetrievable = true, IsFilterable = true, IsSortable = true, IsSearchable = true },
      new Field("details", DataType.String) { IsRetrievable = true, IsFilterable = true, IsSearchable = true },
      new Field("imageUrl", DataType.String) { IsRetrievable = true }
    },
    Suggesters = new[]
    {
      new Suggester("nameSuggester", SuggesterSearchMode.AnalyzingInfixMatching, new[] { "name" })
    }
  };

  searchClient.Indexes.Create(index);
}

屬性 Index.Name 應該設定為索引的名稱,而 Index.Fields 屬性應該設定為 對象的陣列 Field 。 每個 Field 實例都會指定名稱、類型和任何屬性,以指定欄位的使用方式。 這些屬性包括:

  • IsKey – 指出欄位是否為索引鍵。 索引中只有一個類型 DataType.String為 的欄位,必須指定為索引鍵欄位。
  • IsFacetable – 指出是否可以在此欄位上執行多面向導覽。 預設值是 false
  • IsFilterable – 指出欄位是否可用於篩選查詢。 預設值是 false
  • IsRetrievable – 指出是否可以在搜尋結果中擷取字段。 預設值是 true
  • IsSearchable – 指出欄位是否包含在全文搜尋中。 預設值是 false
  • IsSortable – 指出欄位是否可以在表示式中使用 OrderBy 。 預設值是 false

注意

部署索引之後變更索引牽涉到重建和重載數據。

Index物件可以選擇性地指定 Suggesters 屬性,這個屬性會定義索引中要用來支持自動完成或搜尋建議查詢的欄位。 屬性 Suggesters 應該設定為 對象的陣列 Suggester ,以定義用來建置搜尋建議結果的欄位。

建立 Index 對象之後,會在實例上SearchServiceClient呼叫 Indexes.Create 來建立索引。

注意

從必須保持回應的應用程式建立索引時,請使用 Indexes.CreateAsync 方法。

如需詳細資訊,請參閱 使用 .NET SDK 建立 Azure 搜尋服務索引。

刪除 Azure 搜尋服務索引

您可以藉由在 實體上SearchServiceClient呼叫 Indexes.Delete 來移除索引:

searchClient.Indexes.Delete(Constants.Index);

將數據上傳至 Azure 搜尋服務索引

定義索引之後,可以使用兩個模型之一將數據上傳至該索引:

  • 提取模型 – 數據會定期從 Azure Cosmos DB、Azure SQL 資料庫、Azure Blob 儲存體 或裝載在 Azure 虛擬機中的 SQL Server 內嵌。
  • 推送模型 – 數據會以程序設計方式傳送至索引。 這是本文採用的模型。

SearchIndexClient必須建立 實例,才能將數據匯入索引。 呼叫 方法即可達成 SearchServiceClient.Indexes.GetClient 此目的,如下列程式代碼範例所示:

static void UploadDataToSearchIndex()
{
  var indexClient = searchClient.Indexes.GetClient(Constants.Index);

  var monkeyList = MonkeyData.Monkeys.Select(m => new
  {
    id = Guid.NewGuid().ToString(),
    name = m.Name,
    location = m.Location,
    details = m.Details,
    imageUrl = m.ImageUrl
  });

  var batch = IndexBatch.New(monkeyList.Select(IndexAction.Upload));
  try
  {
    indexClient.Documents.Index(batch);
  }
  catch (IndexBatchException ex)
  {
    // Sometimes when the Search service is under load, indexing will fail for some
    // documents in the batch. Compensating actions like delaying and retrying should be taken.
    // Here, the failed document keys are logged.
    Console.WriteLine("Failed to index some documents: {0}",
      string.Join(", ", ex.IndexingResults.Where(r => !r.Succeeded).Select(r => r.Key)));
  }
}

要匯入索引的數據會封裝為 IndexBatch 物件,以封裝物件的集合 IndexAction 。 每個 IndexAction 實例都包含一份檔,以及一個屬性,告知 Azure 搜尋服務要對文件執行哪一個動作。 在上述程式代碼範例中, IndexAction.Upload 會指定動作,這會導致檔在新的索引中插入,或如果檔已經存在,則會加以取代。 然後,物件 IndexBatch 會呼叫 Documents.Index 物件上的 SearchIndexClient 方法,以傳送至索引。 如需其他索引動作的相關信息,請參閱 決定要使用的索引動作。

注意

單一索引要求中只能包含1000份檔。

請注意,在上述程式代碼範例中, monkeyList 集合會從物件的集合 Monkey 建立為匿名物件。 這會建立 id 欄位的數據,並將Pascal案例屬性名稱的對應解析為駱駝式案例 Monkey 搜尋索引功能變數名稱。 或者,您也可以將 屬性新增 [SerializePropertyNamesAsCamelCase]Monkey 類別來完成此對應。

如需詳細資訊,請參閱 使用 .NET SDK 將數據上傳至 Azure 搜尋服務

查詢 Azure 搜尋服務索引

SearchIndexClient必須建立 實例,才能查詢索引。 當應用程式執行查詢時,建議遵循最低許可權原則並直接建立 SearchIndexClient ,以 自變數的形式傳遞查詢密鑰 。 這可確保使用者具有索引和檔的唯讀存取權。 下列程式碼範例會示範這個方法:

SearchIndexClient indexClient =
  new SearchIndexClient(Constants.SearchServiceName, Constants.Index, new SearchCredentials(Constants.QueryApiKey));

SearchIndexClient構函式多載會採用搜尋服務名稱、索引名稱和SearchCredentials物件做為自變數,SearchCredentials而物件會包裝 Azure 搜尋服務 的查詢索引鍵

搜尋查詢

您可以在 實體上SearchIndexClient呼叫 Documents.SearchAsync 方法來查詢索引,如下列程式代碼範例所示:

async Task AzureSearch(string text)
{
  Monkeys.Clear();

  var searchResults = await indexClient.Documents.SearchAsync<Monkey>(text);
  foreach (SearchResult<Monkey> result in searchResults.Results)
  {
    Monkeys.Add(new Monkey
    {
      Name = result.Document.Name,
      Location = result.Document.Location,
      Details = result.Document.Details,
      ImageUrl = result.Document.ImageUrl
    });
  }
}

方法 SearchAsync 會採用搜尋文字自變數,以及可用來進一步精簡查詢的選擇性 SearchParameters 物件。 搜尋查詢會指定為搜尋文字自變數,而篩選查詢可藉由設定 Filter 自變數的 SearchParameters 屬性來指定。 下列程式代碼範例示範這兩種查詢類型:

var parameters = new SearchParameters
{
  Filter = "location ne 'China' and location ne 'Vietnam'"
};
var searchResults = await indexClient.Documents.SearchAsync<Monkey>(text, parameters);

此篩選查詢會套用至整個索引,並從欄位不等於中國且不等於越南的結果 location 中移除檔。 篩選之後,搜尋查詢會在篩選查詢的結果上執行。

注意

若要篩選而不搜尋,請傳遞 * 作為搜尋文字自變數。

方法 SearchAsync 會傳 DocumentSearchResult 回包含查詢結果的物件。 列舉此物件,並建立每個 Document 物件做為 Monkey 物件,並新增至 MonkeysObservableCollection 以顯示。 下列螢幕快照顯示從 Azure 搜尋服務傳回的搜尋查詢結果:

Search Results

如需搜尋和篩選的詳細資訊,請參閱 使用 .NET SDK 查詢您的 Azure 搜尋服務索引。

建議查詢

Azure 搜尋服務可藉由在 實例上SearchIndexClient呼叫 Documents.SuggestAsync 方法,根據搜尋查詢要求建議。 下列程式代碼範例會示範此問題:

async Task AzureSuggestions(string text)
{
  Suggestions.Clear();

  var parameters = new SuggestParameters()
  {
    UseFuzzyMatching = true,
    HighlightPreTag = "[",
    HighlightPostTag = "]",
    MinimumCoverage = 100,
    Top = 10
  };

  var suggestionResults =
    await indexClient.Documents.SuggestAsync<Monkey>(text, "nameSuggester", parameters);

  foreach (var result in suggestionResults.Results)
  {
    Suggestions.Add(new Monkey
    {
      Name = result.Text,
      Location = result.Document.Location,
      Details = result.Document.Details,
      ImageUrl = result.Document.ImageUrl
    });
  }
}

方法 SuggestAsync 會採用搜尋文字自變數、要使用的建議工具名稱(在索引中定義),以及可用來進一步精簡查詢的選擇性 SuggestParameters 物件。 實體會 SuggestParameters 設定下列屬性:

  • UseFuzzyMatching – 當設定為 true時,即使搜尋文字中有替代字元或遺漏字元,Azure 搜尋服務仍會找到建議。
  • HighlightPreTag – 建議叫用前面加上的標籤。
  • HighlightPostTag – 附加至建議點擊的標記。
  • MinimumCoverage – 表示建議查詢必須涵蓋的索引百分比,以便報告查詢成功。 預設值為80。
  • Top – 要擷取的建議數目。 它必須是介於 1 到 100 之間的整數,預設值為 5。

整體效果是,索引的前10個結果會以點擊醒目提示傳回,結果會包含包含類似拼字搜尋字詞的檔。

方法 SuggestAsync 會傳 DocumentSuggestResult 回包含查詢結果的物件。 列舉此物件,並建立每個 Document 物件做為 Monkey 物件,並新增至 MonkeysObservableCollection 以顯示。 下列螢幕快照顯示從 Azure 搜尋服務傳回的建議結果:

Suggestion Results

請注意,在範例應用程式中, SuggestAsync 只有在使用者完成輸入搜尋字詞時,才會叫用 方法。 不過,它也可以用來支持自動完成的搜尋查詢,方法是在每個keypress上執行。

摘要

本文示範如何使用 Microsoft Azure 搜尋服務連結庫將 Azure 搜尋服務整合到 Xamarin.Forms 應用程式中。 Azure 搜尋服務是雲端服務,可為上傳的數據提供索引編製和查詢功能。 這會移除基礎結構需求和搜尋演算法的複雜性,傳統上與在應用程式中實作搜尋功能相關聯。