1. 検索とアイテムのバケット

LINQ to 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を参照してください。

LINQレイヤーは、一般的なクエリを検索プロバイダーが理解できるものに変換する抽象レイヤーです。

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

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

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

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

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

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

LINQレイヤーは、クエリをプロバイダーが理解できるものに変換します。

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

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

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

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

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

次の方法がサポートされています。

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

  • すべての

  • そして

  • 任意

  • 押し上げる

  • キャスト

  • 定数

  • 含む

  • 数える

  • エレメントアット

  • エンデッドウィズ

  • 等しい

  • ファセットオン

  • ファセットピボットオン

  • フィルター

  • まずは

  • GetFacets(エトファセット)

  • 結果を得る

  • グレーターサン

  • より大きいまたは等しい

  • グループ参加

  • インコンテキスト

  • 接続

  • 前の

  • より小さい

  • より小さいまたは等しい

  • という感じで

  • マッチオール

  • 一致

  • マッチなし

  • マックス

  • 打ち消す

  • じゃない

  • 等しくない

  • 又は

  • オーダーバイ

  • OrderByDistance(オーダーバイディスタンス)

  • 選ぶ

  • SelectMany (多数選択)

  • スキップ

  • スタート

  • 取る

  • 組合

  • どこ

  • ワイルドカードマッチ

  • 半径内

  • ToList() ()です。

  • ToLookUp()

  • ToDictionary()

  • スタート

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

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

  • 平均

  • コンキャット

  • ファセット

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

  • グループ化

  • 交わる

  • LastOrDefault

  • マッチ

  • OrderByDescending (降順順)

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

  • スキップWhile

  • テイクWhile

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

LINQ to Sitecore構文

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

Solr syntax

LINQ to Sitecore

Fields

_text:”go”

.Where(c => c.Text == "go") 

-又は:

.Where(c => c.Text.Equals(“go”))

WildCard

_text:*amber*

.Where(c => c.Text.Contains ("amber"))

Prefix

_text: amber*

.Where(c => c.ContactName.StartsWith("amber"))

Fuzzy

_text:roam~

_text:roam~0.8

.Where(c => c.Text.Like("roam"))

.Where(c => c.Text.Like("roam", 0.8))

Proximity

_text:"jakarta apache"~10

.Where(c => 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}

.Where(c => 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 _name:jakarta

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

Boolean And

_name:"jakarta apache" AND _text:"go"

.Where c.Name.Equals("jakarta apache") && c.Text.Equals("go")

Boolean Not

_name:"jakarta apache" NOT _name:"Apache Solr"

.Where c.Name.Equals("jakarta apache") && !c.Name.Equals("Apache Solr")

Grouping

_name:(jakarta OR apache) AND _text:go

where (c.Name == "jakarta" || c.Name == "apache") && (c.Text == "go")

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がインデックス フィールドからアイテムのプロパティにマッピングするプロセスは、「ハイドレーション」とも呼ばれます。

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

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

  • .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; 
        } 
    } 
}
この記事を改善するための提案がある場合は、 お知らせください!