数日から RavenDB を使い始めましたが、すでに何かに行き詰まっています。実行するのは非常に簡単だと思います。
私がやりたいことはTitle
、ユーザーが入力したすべての単語をプロパティに持つ製品のリストを取得するための検索です。
例:
product/1 -> title: "my awesome product"
product/2 -> title: "super product asd"
「prod per」を検索すると、2 番目の製品のみが結果として表示されると予想されます。
私の頭の中で、私はこのようなことをします
public IList<Product> GetBySearchTerms(string searchTerms, int pageIndex, int pageSize, out int totalItems)
{
pageIndex--;
if (pageIndex < 0)
pageIndex = 0;
IList<Product> result = new List<Product>();
var query = var query = session.Query<Product>().Statistics(out stats);
var termsList = searchTerms.Split(' ', StringSplitOptions.RemoveEmptyEntries);
foreach (var term in termsList)
query = query.Where(x => x.Title.Contains(term));
if (pageSize > 0)
result = query.Skip(pageIndex * pageSize).Take(pageSize).ToList();
else
result = query.ToList();
totalItems = stats.TotalResults;
return result;
}
Contains
掘り下げた後、最初の問題はメソッドにあることがわかりました。RavenDB での検索の動作が原因で、実装/サポートされていません。
代わりにメソッドを使用する必要がありますが、パフォーマンスの問題のために使用すべきではないことSearch
も読みました。*term*
だから私はこのようなRavenDBでインデックスを作成することになりました
Name: ProductSearchByName
Map: from doc in docs.Products select new { Title = doc.Title }
そしてコード
public IList<Product> GetBySearchTerms(string searchTerms, int pageIndex, int pageSize, out int totalItems)
{
pageIndex--;
if (pageIndex < 0)
pageIndex = 0;
IList<Product> result = new List<Product>();
RavenQueryStatistics stats;
var query = session.Query<Product>("ProductSearchByName").Statistics(out stats);
query = searchTerms
.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries)
.Aggregate(query, (q, term) => q.Search(x => x.Title, "*" + term + "*", options: SearchOptions.And, escapeQueryOptions: EscapeQueryOptions.AllowAllWildcards));
if (pageSize > 0)
result = query.Skip(pageIndex * pageSize).Take(pageSize).ToList();
else
result = query.ToList();
totalItems = stats.TotalResults;
return result;
}
この検索は必要なことを実行しますが、ワイルドカードの使用に関するすべての警告が心配です。
Contains
を使用せずに結果を取得する方法はあり*term*
ますか?
この問題に対する正しいアプローチ/解決策は何ですか?