Solr のフィールド名解決の使用

概要

Sitecore がドキュメント (アイテム) のフィールド名を Solr のフィールド名に自動的にマップする仕組みの概要。

Solr を検索プロバイダーとして利用する場合、ドキュメントのインデックス作成と検索については一定の規則が決められています。Sitecore がインデックス作成のためにドキュメント (アイテム) を Solr に送信する場合、アイテムの各フィールドを Solr のフィールドにマップする必要があります。マッピングの例としては、Sitecore の Item Name フィールドを Solr の _name フィールドにマップする場合などが挙げられます。

多数の Sitecore フィールドを Solr フィールドに手動で一致させる作業は現実的とはいえません。そこで、Solr の動的フィールドを使用して、Sitecore フィールドへの自動マッピングを実行できます。

自動マッピングの例としては、Sitecore が Sitecore の計算された parsedcreatedby 文字列フィールドを Solr の parsedcreatedby_s 動的文字列フィールドにマップする場合が挙げられます。parsedcreatedby は、Sitecore の string インデックス フィールド タイプに関連付けられており、*_s というフィールド名の形式にマップされるためです。

すべてのマッピングは、Sitecore.ContentSearch.Solr.DefaultIndexConfiguration.config ファイルで指定します。

たとえば、amount という名前の Sitecore フィールドについて考えてみましょう。数字を保持するフィールドなので、Sitecore の number タイプ フィールドです。Sitecore フィールドが、名前によって手動でインデックス フィールド タイプにマッピングされていない場合、Sitecore は自動的に Sitecore のフィールド タイプ別に Solr 動的フィールドにマップします。処理の順序は、以下のとおりです。

  1. AddFieldByFieldTypeName セクションで、Sitecore が Sitecore の number タイプ フィールドを Solr の float タイプ フィールドにマップします。

    <fieldTypes hint="raw:AddFieldByFieldTypeName">
      <fieldType fieldTypeName="number" returnType="float" />
      ...
    </fieldType>
  2. AddTypeMatch セクションで、Sitecore が Solr の float タイプ フィールドを {0}_tf というフィールド名の形式にマップします。

    <typeMatches hint="raw:AddTypeMatch">
      <typeMatch
        typeName="float"
        type="System.Single"
        fieldNameFormat="{0}_tf"
        settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration,
          Sitecore.ContentSearch.SolrProvider"
      />
      ...
    </typeMatches>
  3. Sitecore が {0} の部分を Sitecore の amount フィールド名に置き換え、Solr の amount_tf フィールド名に解決します。

  4. Sitecore が、amount という名前の Sitecore の number タイプ フィールドを、amount_tf という名前の Solr の動的な float タイプ フィールドとしてインデックス付けします。

フィールド名によるマッピングのオーバーライド

Sitecore は、AddFieldByFieldName セクションの各フィールドについて、AddFieldByFieldTypeName セクションのマッピングをオーバーライドできます。たとえば、この機能を使用して、Sitecore の title フィールドを、title_t という名前の Solr の text タイプ フィールドとしてインデックス付けできます。Sitecore は、Solr のフィールド タイプと一致させる場合に、Sitecore フィールドのタイプではなく名前を使用します。

<fieldTypes hint="raw:AddFieldByFieldName">
  <field fieldName="title" returnType="text" />
  ...
</fieldTypes>

計算フィールドのインデックス作成

Sitecore は、AddComputedIndexField および AddTypeMatch セクションで、Sitecore の計算フィールドを Solr の動的フィールドにマップします。たとえば、Sitecore は Sitecore の calculateddimension 計算フィールドを Solr の stringCollection タイプ フィールドにマップし、次のように calculateddimension_sm としてインデックス付けします。

<fields hint="raw:AddComputedIndexField">
  <field fieldName="calculateddimension" returnType="stringCollection">
  Sitecore.ContentSearch.ComputedFields.CalculatedDimension,Sitecore.ContentSearch
  </field>
  ...
</fields>

<typeMatches hint="raw:AddTypeMatch">
  <typeMatch
    typeName="stringCollection"
    type="System.Collections.Generic.List`1[System.String]"
    fieldNameFormat="{0}_sm"
    multiValued="true"
    settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration,
      Sitecore.ContentSearch.SolrProvider"
  />
  ...
</typeMatches>

Sitecore は、検索とインデックス作成でほぼ同じ方法を使用してフィールドを解決します。ただし、フィールドと値のタイプに関する情報が欠落しているため、わずかな違いがあります。たとえば、title:Casablanca を検索する場合、Sitecore は次の順序で title フィールド タイプを Solr のフィールド名形式に解決します。

  1. Sitecore が、title フィールドを含むテンプレートを特定します。

  2. Sitecore が、title フィールド タイプが Single-Line Text であることを確認します。

  3. AddFieldsByTypeName セクションで、Sitecore が Sitecore の single-line text フィールド タイプを Solr の text フィールド タイプにマップします。

    <fieldTypes hint="raw:AddFieldByFieldTypeName">
      <fieldType
        fieldTypeName="html|rich text|single-line text|multi-line text|text|memo|image|reference"
        returnType="text"
      />
      ...
    </fieldTypes>
  4. AddTypeMatch セクションで、Sitecore が Solr の text フィールド タイプを {0}_t というフィールド名の形式にマップします。

    <typeMatches hint="raw:AddTypeMatch">
      <typeMatch
        typeName="text"
        type="System.String"
        fieldNameFormat="{0}_t"
        cultureFormat="_{1}"
        settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration,
          Sitecore.ContentSearch.SolrProvider"
      />
    </typeMatches>
  5. Sitecore が {0} の部分を Sitecore の title フィールド名に置き換え、Solr の title_t フィールド名に解決します。

  6. Sitecore が、検索クエリを Solr に送信します。

    /select?q=title_t:Casablanca

LINQ で検索する

Sitecore は、LINQ を使用して厳密に型指定されたプロパティによって検索要求を実行する場合、.NET ランタイム タイプのプロパティを使用して、AddTypeMatch セクションで Solr のフィールド名を解決します。

var queryable = index.CreateSearchContext().GetQueryable< CustomSearchResultItem >();
var q = queryable.Where(i => i.Airport.Equals("search term")).ToList();

public class CustomSearchResultItem : SearchResultItem {
  [IndexField("Airport")]
  [DataMember]
  public virtual string Airport { get; set; }
}

ただし Sitecore が、AddTypeMatchセクションでフィールド タイプ名を複数の .NET ランタイム タイプにマップできる状況では、テンプレート リゾルバーを使用して Solr にテンプレートとフィールド タイプを問い合わせます。

たとえば、Sitecore の airport プロパティは System.String タイプですが、AddTypeMatch セクションで stringtext の両方の .NET ランタイム タイプにマップします。そのため、2 つのフィールド名形式 ({0}_s および {0}_t) と 2 つの Solr 動的フィールド名 (airport_s および airport_t) が生成されることになります。

<typeMatches hint="raw:AddTypeMatch">
  <typeMatch
    typeName="string"
    type="System.String"
    fieldNameFormat="{0}_s"
    settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration, 
      Sitecore.ContentSearch.SolrProvider"
  />
  <typeMatch
    typeName="text"
    type="System.String"
    fieldNameFormat="{0}_t"
    cultureFormat="_{1}"
    settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration, 
      Sitecore.ContentSearch.SolrProvider"
  />
  ...
</typeMatches>

Sitecore は、テンプレート リゾルバーを使用して、テンプレートとフィールド タイプを次の順序で Solr に照会します。

  1. Sitecore が、リゾルバーの要求を Solr に送信します。次に例を示します。

    /select?q=_name:(airport)&fq=_templatename:("Template+field")&fq=_indexname:(sitecore_master_index)&rows=10&version=2.2}

    重要

    2 つのテンプレートが両方とも同じフィールド (たとえば airport フィールド) を定義している場合、テンプレート リゾルバーは 2 つの結果を不特定の順序で返します。Sitecore は常に最初の結果を選択するため、解決に一貫性がなくなります。これは airport が、あるテンプレートでは Single-Line Text フィールド タイプとして定義され、別のテンプレートでは Droplist フィールド タイプとして定義されている場合に特に問題となります。

  2. Solr が single-line text フィールド タイプを返します。これは Sitecore が、AddFieldByFieldTypeName セクションで Solr の text フィールド タイプにマップします。

    <fieldTypes hint="raw:AddFieldByFieldTypeName">
      <fieldType
        fieldTypeName="html|rich text|single-line text|multi-line text|text|memo|image" 
        returnType="text"
      />
    </fieldTypes>
  3. AddTypeMatch セクションで、Sitecore が Solr の text フィールド タイプを {0}_t というフィールド名の形式にマップします。

    <typeMatches hint="raw:AddTypeMatch">
      <typeMatch
        typeName="text"
        type="System.String"
        fieldNameFormat="{0}_t"
        cultureFormat="_{1}"
        settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration,
          Sitecore.ContentSearch.SolrProvider"
      />
    </typeMatches>
  4. Sitecore が {0} の部分を Sitecore の airport プロパティ名に置き換え、Solr の airport_t フィールドに解決します。

  5. Sitecore が、最終的な検索クエリを Solr に送信します。

    /select?q=_airport_t:”search term”&fq=_indexname:(sitecore_master_index)

Sitecore のコンテンツ検索は、完全かつ満足のいく検索結果を提供するために、インデックス付けされたテンプレートに依存していますが、これはフィールド タイプが正しく解決されていることが前提となります。テンプレートのインデックスを作成しない構成の例は次のとおりです。

  • /sitecore/templates サブツリーを含まない、クローラーの Root タグ。

    <crawler
      type="Sitecore.ContentSearch.SitecoreItemCrawler,
        Sitecore.ContentSearch">
      <Database>master</Database>
      <Root>/sitecore/content</Root>
    </crawler>
  • テンプレート フィールド アイテムを除外するように設定されたインデックス ドキュメント オプション。

    <exclude hint="list:AddExcludedTemplate">
      <TemplateField>{455A3E98-A627-4B40-8035-E683A0331AC7}</TemplateField>
    </exclude>

構成で必要な場合は、テンプレートがインデックス付けされるように TemplateIndexName タグを追加します。このタグは、/sitecore/templates ルートにあるすべてのテンプレート フィールド アイテムにクローラーがインデックス付けを行うインデックスを指している必要があります。

<index
  id="sitecore_master_index"
  type="Sitecore.ContentSearch.SolrProvider.SolrSearchIndex, 
    Sitecore.ContentSearch.SolrProvider">
  ...
  <TemplateIndexName>TEMPLATE INDEX NAME</TemplateIndexName>
</index>

TemplateIndexName を指定すると、Sitecore のコンテンツ検索は、Solr に対するクエリで使用される Sitecore フィールドの Solr マッピングを正しく解決できます。テンプレートのインデックス付けに失敗すると、検索要求が失敗したり、検索結果が空になったりする場合があります。