Version: 2023.1
言語: 日本語
検索プロバイダーの登録
アクションハンドラーの登録

検索の実行

検索プロバイダーは、fetchItems 関数を使用して、アイテムの検索と結果のフィルタリングを行います。fetchItems 関数は以下のシグネチャを持っています。

//context: 必要な検索コンテキスト (例えば、トークンによる検索や
// サブフィルターなど)
// items: 検索するアイテムのリスト (非同期 API を使用しない場合)
// provider: 検索プロバイダー自体
public delegate IEnumerable<SearchItem> GetItemsHandler(SearchContext context,
                                    List<SearchItem> items,
                                    SearchProvider provider);

SearchProvider は、新しい SearchItemitems リストに追加するか、IEnumerable<SearchItem> を返さなければなりません。

ノート: 非同期 fetchItems API を使用しない場合、fetchItems 関数で null を返さなければなりません。

SearchItem は単純な構造体です。

public struct SearchItem
{
    public readonly string id;
    // アイテムのスコアは、検索プロバイダーからの結果内で Search がアイテムをどのようにソートするかに影響します。
    public int score;
    //任意。アイテムの表示名。アイテムに名前がない場合。
    // SearchProvider.fetchLabel が呼び出されます。
    public string label;
    // アイテムが説明を持っていない場合、
    // Search が最初にアイテムを表示するときに SearchProvider.fetchDescription が呼び出されます。
    public string description;
    // true の場合、説明文はすでにリッチテキスト形式です。
    public SearchItemDescriptionFormat descriptionFormat;
    // アイテムにサムネイルがない場合、
    // Search が最初にアイテムを表示するときに SearchProvider.fetchThumbnail が呼び出されます。
    public Texture2D thumbnail;
    // 検索プロバイダーのユーザーカスタマイズが可能なコンテンツ
    public object data;
}

SearchItem では id だけが必須です。

ヒント: SearchContext.searchText に従ってフィルタリングする場合、静的関数 SearchProvider.MatchSearchGroup で部分検索を行うことができます。

ファジーサーチの使用

アイテムに対してファジーサーチを使うには、以下の例のように FuzzySearch.FuzzyMatch を使用します。

if (FuzzySearch.FuzzyMatch(sq, CleanString(item.label), ref score, matches))
    item.label = RichTextFormatter.FormatSuggestionTitle(item.label, matches);

すべての検索アイテムは、同じプロバイダーのアイテムに対して score でソートされます。スコアが低い アイテムがリストの一番上に表示されます (昇順ソート )。

非同期検索 API

非同期 fetchItems API は、検索プロバイダーの結果計算に時間がかかる場合や、WebRequests などの非同期検索エンジンに依存する場合に使用できます。

非同期 API を使用するには、fetchItems 関数が IEnumerable<SearchItem> を返すようにします。IEnumerable<SearchItem> は、結果を返す関数である必要があります。API が一度に 1 つのアイテムをフェッチできるからです。

IEnumerable<SearchItem> が返されると、アプリケーションの更新の間にエニュメレーターが保存され、繰り返し実行されます。列挙型は、終了するまで、複数のアプリケーションの更新にわたって継続されます。

UI がブロックされないように反復処理時間は制限されます。ただし、この呼び出しはメインスレッドで行われるため、結果が準備できない場合は、できるだけ早く yield する必要があります。

以下の例は、非同期の fetchItems API を使用する方法を示しています。

public class AsyncSearchProvider :SearchProvider
{
    public AsyncSearchProvider(string id, string displayName = null)
        : base(id, displayName)
    {
        fetchItems = (context, items, provider) =&gt; FetchItems(context, provider);
    

    private IEnumerable<SearchItem>FetchItems(SearchContext context, SearchProvider provider)
    {
        while(ResultsNotReady())
        {
            yield return null;
        

        var oneItem = // アイテムを取得
        yield return oneItem;

        var anotherItem = // 別のアイテムを取得
        yield return anotherItem;

        if(SomeConditionThatBreaksTheSearch())
        {
            // 検索を終了しなければなりません。
            yield break;
        

        // 列挙可能なものに対して反復処理を行うことができます。
        // 列挙は前に終了したところから続行します。
        foreach(var item in someItems)
        {
            yield return item;
        }
    }
</SearchItem>
  • AssetStoreProvider.cs: WebRequest を使って Asset Store にクエリを行います。
  • ESS.cs: Entrian Source 検索インデックスを起動するプロセスを作成し、プロジェクト内のアセットに対する完全なテキスト検索を提供します。
検索プロバイダーの登録
アクションハンドラーの登録