
当社が全文検索プラットフォームとしてSolrを選択したという事実により、LINQ式を使用してSolrクエリの作業を簡素化したいという強い要望がありました。
代替手段が利用できるようにインターネットを再構築したところ、現時点ではパブリックドメインに必要なライブラリはないという結論に達しました。 私が見つけた最大のものは、Solr.NET でのリクエストの非常に部分的な実装でした(そして著者自身の懐疑的なコメント )。
その結果、小さなライブラリLinqToSolr ( GitHubプロジェクト )が作成されました。このライブラリには、リクエストを明確なSolr APIに、またはその逆に変換できるIQueriable <>インターフェースの実装が含まれています。
実装可能な列挙可能なメソッド
現在、次のメソッドの実装が利用可能です。
- どこで
- 最初に
- FirstOrDefault
- 選択してください
- Groupby
- GroupByFacets-ファセットを使用するための追加の方法
- 取る
- スキップする
- オーダーバイ
- それでは
- OrderByDescending
- ThenByDescending
構成
そのため、まず接続を構成し、データモデルとSolrインデックスの比率を調整する必要があります。
構成から始めますが、最初にSolr文書の表現を通常のクラスとして定義します。
public class MyProduct{ [JsonProperty("ProductId")] public int Id{get;set;} public string Name{get;set} public string Group{get;set} public double Price {get;set;} public bool IsDeleted{get;set} }
上記は、ID、名前、グループ、価格、IsDeletedの各入力フィールドを持つSolrインデックスを記述するクラスです。 必要に応じて、JsonPropertyプロパティを使用してフィールド名(たとえば、IDフィールド)を再定義できます。
構成を作成しましょう:
var config = new LinqToSolrRequestConfiguration("http://localhost:1433/") .MapIndexFor<MyProduct>("MyProductIndex");
ここで何が見えますか? まず、Solrに住所を提供します。
次に、クラスのソーラーインデックスへの投影を示します。 任意の数のクラスを異なるインデックスに指定できると仮定するのは自然です。 唯一の条件は、1つのクラスが単一のインデックスに対応する必要があるということです。 最小構成の準備ができました。
サービス自体を初期化します。
var service = new LinqToSolrService(config);
それだけです Linq to Solrの使用を開始するためのすべての条件を満たしました。
使用例
FirstOrDefaultメソッド
service.AsQueriable<MyProduct>().FirstOrDefalult(x=> x.Id == 1);
どこメソッド
グループのすべてのドキュメントを選択します。
service.AsQueriable<MyProduct>().Where(x=>x.Group == "Group1").ToList();
linqクエリ内で関数を使用する実装例:
service.AsQueriable<MyProduct>().Where(x=>x.Group.Contains("roup")).ToList(); service.AsQueriable<MyProduct>().Where(x=>x.Group.StartsWith("Gro")).ToList(); service.AsQueriable<MyProduct>().Where(x=>x.Group.EndsWith("up1")).ToList();
配列検索の例:
var groupsArr= new[] { "Group1", "Group2", "Group3" }; service.AsQueriable<MyProduct>().Where(x=> groupsArr.Contains(x.Group)).ToList();
より少ないサンプルの例:
service.AsQueriable<MyProduct>().Where(x=> x.Price >= 500 && x.Price < 1000).ToList();
複数のWhereを使用します。
service.AsQueriable<MyProduct>() .Where(x=> !x.IsDeleted) .Where(x=>x.Name.Contains("somepartofthename")) .ToList();
ドキュメントを並べ替える
service.AsQueriable<MyProduct>() .Where(x=> !x.IsDeleted) .OrderByDescending(x=> x.Group) // DESC .ThenBy(x=>x.Name) // ASC .ToList();
特定の番号を選択してください
service.AsQueriable<MyProduct>().Where(x=> !x.IsDeleted).Take(100).Skip(400).ToList();
選択方法
// service.AsQueriable<MyProduct>().Where(x=> !x.IsDeleted).Select(x=> x.Name).ToList(); // dynamic- service.AsQueriable<MyProduct>().Where(x=> !x.IsDeleted).Select(x=> new {x.Name, x.Group}).ToList();
ファセットを使用する
service.AsQueriable<MyProduct>().Where(x=> !x.IsDeleted).GroupByFacets(x=>x.Name, x=>x.Group).ToList();
上記の例では、Solrに2つのグループ(名前とグループ)を返すように依頼しています。
GroupByメソッドを使用することもできます。 彼は、同様のオプションを返しますが、グループ化されたドキュメントも追加します。 使用する方が良いのはあなた次第です。 ファセットは高速ですが、ドキュメントのリストを取得するには、サーバーに2つのリクエストを行う必要があります。 GroupBy-グループに加えて、ドキュメント自体が既にグループでソートされているため、返されるため、動作が遅くなります。
デバッグと検証
いずれにせよ、要求と応答を確認する必要が生じます。 これは、サービスに組み込まれたLastResponseオブジェクトを使用して実行できます。 実際、これはSolrサーバーの応答の表現です。 さらに、リクエストのURL(LastRequestUrl)があります。これは、Solrが実際に返すものを確認するためにブラウザーで使用できます。
サービス
当然、LinqToSolrServiceを直接使用することはあまり便利ではありません。 LinqToSolrServiceから継承した独自のサービスを作成します。
public class MySolrService : LinqToSolrService { public MySolrService(LinqToSolrRequestConfiguration config) : base (config) { } public IQueryable<MyProduct> NotDeleted() { return AsQueryable<MyProduct>().Where(x=> !x.IsDeleted); } public ICollection<MyProduct> GetProducts(params int[] ids) { return NotDeleted().Where(x=> ids.Contains(x.Id)).OrderBy(x=>x.Name).ToList(); } public MyProduct GetProduct(id) { return NotDeleted().FirstOrDefault(x=> x.Id == id); } public string[] GetGroups(id) { return NotDeleted().GroupBy(x=> x.Group).ToArray(); } }
まとめ
.NETプロジェクトでSolrを使用している人が、このライブラリが役に立つことを願っています。
現時点では、最も明白なクエリが実装されています。
Boost、Proximity、リクエスト機能のサポートを追加する計画。