LINQからSitecoreへ

Version:
日本語翻訳に関する免責事項

このページの翻訳はAIによって自動的に行われました。可能な限り正確な翻訳を心掛けていますが、原文と異なる表現や解釈が含まれる場合があります。正確で公式な情報については、必ず英語の原文をご参照ください。

LINQ to Sitecoreでは、LINQ to SQLやLINQ to Objectsなどの他のLINQプロバイダーと同様に、標準のLINQクエリを使用してインデックスを検索できます。標準のIQueryable<T> インターフェイスを使用し、使用可能なほとんどの操作をサポートします。LINQの一般的な概要については、http://msdn.microsoft.com/en-us/library/vstudio/bb397926.aspxを参照してください。

Sitecoreは、LuceneとSolrの2つの検索プロバイダーをサポートしています。LINQレイヤーは、一般的なクエリをこれらの検索プロバイダーが理解できるものに変換する抽象レイヤーです。

たとえば、LINQレイヤーは次のようなクエリを解決します。

var query = context.GetQueryable<Product>.Where(item => item.Name == “Sample Item”) 

SolrまたはLuceneが理解できるものに。新しい検索プロバイダーを実装すると、このプロバイダーもクエリを理解できます。

LINQレイヤーはSitecoreによって内部的に使用されますが、開発者も使用できます。このレイヤーは、サブレイアウトで使用できます。

検索を開始するには、検索コンテキストを設定します。

using (var context = ContentSearchManager.GetIndex(item).CreateSearchContext())
{
    IQueryable<SearchResultItem> searchQuery = context.GetQueryable<SearchResultItem>().Where(item => item.Name == “Sitecore”)
}

LINQレイヤーは、クエリをプロバイダーが理解できるものに変換します。たとえば、Luceneの場合、次のように変換されます。

_name:sitecore

これにより、検索インデックスに対するクエリの結果が返され、SearchResultItemタイプとして返されます。インデクサーを使用してクエリを実行することもできます。

using (var context = ContentSearchManager.GetIndex(item).CreateSearchContext())
{
    IQueryable<SearchResultItem> searchQuery = context.GetQueryable<SearchResultItem>().Where(item => item[“_name”] == “Sitecore”)
}

このトピックでは、次の内容について説明します。

サポートされているIQueryableメソッド

LINQレイヤーは、すべてのIQueryableメソッドを実装しているわけではありません。次のメソッドが実装されています。

  • 標準の文字列、整数、浮動小数点数、または実装されている任意の型で並べ替えます IComparable

  • すべての

  • 任意

  • Between (開始範囲と終了範囲を含めるか除外するための追加のオーバーロードを使用)

  • ブースト (クエリのこの部分を他の部分よりも重要にします)

  • キャスト (Selectの代わりにこれを使用できます)

  • 含む

  • 数える

  • エレメントアット

  • エンデッドウィズ

  • 等しい

  • ファセット (述語のファセットをフェッチする拡張機能)

  • まずは

  • FirstOrDefault (最初またはデフォルト)

  • 接続

  • 前の

  • LastOrDefault

  • マックス

  • Match (正規表現クエリを実行するための拡張機能)

  • オーダーバイ

  • OrderByDescending (降順順)

  • 選ぶ

  • SingleOrDefault (シングルまたはデフォルト)

  • スキップ

  • 取る

  • ToList() ()です。

  • ToLookUp()

  • ToDictionary()

  • ページ(スキップとテイクを自動的に実行する拡張機能)

  • スタート

サポートされていないIQueryableメソッド

次の方法はサポートされていません。

  • グループ化

  • GroupByJoin (グループ・バイ・ジョイン)

  • 交わる

  • 平均

  • コンキャット

  • テイクWhile

  • スキップWhile

  • 組合

これらのメソッドが呼び出されると、実行時にNotSupportedExceptionまたはInvalidOperationException例外がスローされます。

LINQ to Sitecore構文

次の表は、LINQレイヤーとLuceneの対応を示しています。

Lucene syntax

LINQ to Sitecore

Fields

text:”go”

c.Text == "go" 又は

c.Text.Equals(“go”)

WildCard

text:*amber*

c.Text.Contains ("amber")

Prefix

text: *amber

c.ContactName.StartsWith("amber")

Fuzzy

text:roam~

text:roam~0.8

c.Text.Like("roam")

c.Text.Like("roam", 0.8)

Proximity

text:"jakarta apache"~10

c.Text.Like("jakarta apache", 10)

Inclusive Range

__smallupdateddate:20140101 TO 20150101

.Where(c => c.Updated.Between(new DateTime(2014, 1, 1), new DateTime(2015, 1, 1), Inclusion.Both)

Exclusive Range

title:{Aida TO Carmen}

c.Title.Between("Aida", "Carmen", Inclusion.None)

Boosting

name:jakarta^4 apache

.Where(c => c.Name.Equals("jakarta").Boost(4) || c.Name.Equals("apache"))

Boolean Or

name:"jakarta apache" OR jakarta

where c.Name.Equals("jakarta apache") || c.Equals("jakarta")

Boolean And

"jakarta apache" AND "Apache Lucene"

where c.Equals("jakarta apache") && c.Equals("Apache Lucene")

Boolean Not

"jakarta apache" NOT "Apache Lucene"

where c.Equals("jakarta apache") && !c.Equals("Apache Lucene")

Grouping

(jakarta OR apache) AND website

where (c.Title == "jakarta" || c.Title == "apache") && (c.Title == "website")

IQueryable拡張機能

LINQレイヤーには、標準のIQueryableインターフェイスを拡張する追加のメソッドが用意されています。それらを使用するには、Sitecore.ContentSearch.Linq名前空間を宣言する必要があります。

フィルタリング

フィルタリングは、Whereを使用して結果リストを制限するのと似ています。 Filterを使用すると、検索ヒットのスコアリング/ランキングはフィルターの影響を受けず、フィルターをキャッシュして検索パフォーマンスを最適化できます。

例えば:

results = queryable.Filter(d => d.Id > 4 && d.Id < 8);
メモ

検索結果のランク付けに影響を与えないようにするには、GetGlobalFiltersパイプライン内の検索クエリに制限を適用するときにFilterを使用します。

ファセット

シンプルなファセット

var results = queryable.FacetOn(d => d.Name); 
var facets = results.GetFacets(); 
foreach (var category in facets.Categories) { 
    Console.WriteLine(category.Name); 
    foreach (var facetValue in category.Values) { 
        Console.WriteLine("{0}: {1}", facetValue.Name, facetValue.Aggregate); 
    } 
}

ピボットファセット

var results = queryable.FacetPivotOn(p => p.FacetOn(d => d.Name).FacetOn(d => d.Year)); 
var facets = results.GetFacets(); 
foreach (var category in facets.Categories) { 
    Console.WriteLine(category.Name); 
    foreach (var facetValue in category.Values) { 
        Console.WriteLine("{0}: {1}", facetValue.Name, facetValue.Aggregate); 
    } 
}

高める

queryable.Where(it => (it.TemplateName == "Sample Item").Boost(50) || it.TemplateName=="Folder");
queryable.Where(it => (it.Paths.Contains(new ID("{0DE95AE4-41AB-4D01-9EB0-67441B7C2450}")).Boost(3) || it.TemplateName=="Folder") );

results = queryable.Where(item => item.Price.Between(50.0f, 400.0f, Inclusion.Both));
results = queryable.Where(item => item.Price.Between(2.0f, 12.0f, Inclusion.Both) || item.Price.Between(80.0f, 400.0f, Inclusion.Both)); 
results = queryable.Where(d => d.Date.Between(new DateTime(2004, 12, 31), DateTime.Now, Inclusion.Both)); 
results = queryable.Where(d => d.Id.Between(1, 4, Inclusion.Both)); 
results = queryable.Where(d => d.Id.Between(1, 4, Inclusion.Lower)); 
results = queryable.Where(d => d.Id.Between(1, 4, Inclusion.Upper)); 
results = queryable.Where(d => d.Id.Between(1, 4, Inclusion.None)); 

糸。含む

results = queryable.Where(d => !d.Template.Contains("Hello:));

糸。比較先

results = queryable.Where(d => !d.Name.CompareTo("Hello") == 1);

等しい

results = queryable.Where(d => d.Id.Equal(4));

一致

results = queryable.Where(i => i.Template.Matches("^.*$")); 

マッチワイルドカード

results = queryable.Where(i => i.Template.Where(i => i.Template.MatchWildcard("H?li*m")));

という感じで

results = queryable.Where(i => i.Template.Like("Citecoar")); 

糸。スタート

results = queryable.Where(d => !d.Name.StartsWith("Hello")); 

糸。エンデッドウィズ

results = queryable.Where(d => !d.Name.EndsWith("Hello"));

結果を得る

results = queryable.GetResults().Hits.Where(i => i.Document.Name.Contains("o")).Where(hit => hit.Score > 0.6); 

GetFacets(エトファセット)

results = queryable.Where(d => d.Id > 0).FacetOn(d => d.Template, 0).GetFacets();

カスタム検索タイプ/オブジェクトマッピング

LINQレイヤーは汎用IQueryable<T> インターフェイスを使用して検索インデックスを公開するため、カスタム クラスまたはPOCOクラスを使用してインデックス内の情報を記述できます。

カスタム検索タイプを実装するには、次のようなクラスで次のことを行う必要があります。

  • 空のコンストラクターを用意します。

  • 検索結果データを保持するためのgetterとsetter、および/またはパブリック インデクサーを使用してパブリック プロパティを公開します。

LINQプロバイダは、インデックス内のドキュメント フィールドを、プロパティの名前によってカスタム検索の種類のプロパティに自動的にマップします。名前で一致していないインデックスのプロパティまたはフィールドは、オブジェクトの作成/マッピング中にスキップされます。

また、インデックス内のフィールドと一致しないプロパティを、IndexField属性で修飾することでマップすることもできます。たとえば、これを使用して、_nameなどの特別なSitecoreフィールドをNameというプロパティとして公開できます。別の使用例は、スペースを含むフィールド名で、名前で直接プロパティにマッピングできないためです。

さらに、キーとしてのフィールド名と、インデックス ドキュメント内の各フィールドの値が入力されるインデクサーを実装できます。また、インデクサーを異なる型としてラップするために使用できるObjectIndexerKeyもあります。これは、プロパティ名の文字列バージョンしかないが、それをプロパティ型のインデクサーとして使用する必要がある場合 (ほとんどの場合、intが必要になる) 場合に便利です。

カスタム タイプを指定し、Sitecoreがインデックス フィールドからアイテムのプロパティにマッピングするプロセスは、「ハイドレーション」とも呼ばれます。

使用されている検索プロバイダーによっては、インデックスにインデックスが付けられ、格納されているデータが値のネイティブ型ではない場合があります。Luceneの場合、すべてが文字列として格納され、インデックスが付けられます。

サポートされているタイプ

インデックスドキュメントフィールドをプロパティにマッピングする際の自動型変換では、次の型がサポートされています。

  • .NET組み込み整数型

  • .NETの組み込み浮動小数点型

  • ブーリアン

  • 日時

  • GUIDの

  • サイトコアID

  • SitecoreショートID

  • サイトコアItemUri

  • IEnumerable<T>

  • 日時オフセット

  • 言語

  • バージョン

  • データベース

  • カルチャー情報

  • タイムスパン

カスタム検索タイプの例

以下は、カスタム検索タイプを実装する方法の簡単な例です。

public class MySearchResultItem 
{
    // Fields 
    private readonly Dictionary<string, stringfields = new Dictionary<string, string>(); 
    // Properties 
    // Will match the _name field in the index 
    [IndexField("_name")] 
    public string Name { get; set; } 
    // Will match the myid field in the index 
    public Guid MyId { get; set; } 
    public int MyNumber { get; set; } 
    public float MyFloatingPointNumber { get; set; } 
    public double MyOtherFloatingPointNumber { get; set;} 
    public DateTime MyDate { get; set; } 
    public ShortID MyShortID { get; set; } 
    public ID SitecoreID { get; set; } 
    // Will be set with key and value for each field in the index document 
    public string this[string key]
    { 
        get 
        { 
            return this.fields[key.ToLowerInvariant()]; 
        } 
        set 
        { 
            this.fields[key.ToLowerInvariant()] = value; 
        } 
    } 
}
この記事を改善するための提案がある場合は、 お知らせください!