開発メモ
環境:ASP.NET MVC5
商品検索を想定
メーカーの指定がある場合は、検索キーワードに足して検索を行う。
#モデルクラス
public class SearchViewModel
{
public string Keyword { get; set; } //検索キーワード
public IList<SearchModel> ResultItems { get; set; }//検索結果
}
public class SearchModel
{
public string Item_name { get; set; }//商品名
public int Price { get; set; }//金額
public string Maker_name { get; set; }//メーカー名
}
#アクション
public ActionResult Search(SearchViewModel model, string makerName, string lowerLimitPrice, string upperLimitPrice)
{
//クライアントを生成
connectionSettings = new ConnectionSettings(new Uri("127.0.0.1"));
elasticClient = new ElasticClient(connectionSettings.DefaultIndex("hoge"));
IList<SearchModel> hits = new List<SearchModel>();
// 検索条件
var condition = new QueryContainer();
var search = new SearchDescriptor<SearchModel>();
search.Type("fuga");
search.Size(100);//100件取得
//検索キーワードをセット
if (!string.IsNullOrEmpty(model.Keyword))
{
var tq1 = Query<SearchModel>.Term(p => p.Item_name, model.Keyword);
var tq2 = Query<SearchModel>.Term(p => p.Maker_name, model.Keyword);
//商品名かメーカー名でヒットするようにshould(OR)でセット
condition = tq1 || tq2;
}
if (!string.IsNullOrEmpty(makerName))
{
// メーカー名の条件を生成
var tq3= Query<SearchModel>.Term(p => p.Maker_name, makerName);
//メーカー名をmust(AND)で追加
condition = condition && tq3;
}
//価格帯をセット
if (int.TryParse(lowerLimitPrice, out int lowerLimit) && int.TryParse(upperLimitPrice, out int upperLimit))
{
//下限~上限
var rg = Query<SearchModel>.Range(r => r.Field(p => p.Selling_price).GreaterThanOrEquals(lowerLimit).LessThanOrEquals(upperLimit));
condition = condition && rg;
}
else if (int.TryParse(lowerLimitPrice, out lowerLimit))
{
//下限~
condition = condition && Query<SearchModel>.Range(r => r.Field(p => p.Selling_price).GreaterThanOrEquals(lowerLimit));
}
else if (int.TryParse(upperLimitPrice, out upperLimit))
{
//~上限
condition = condition && Query<SearchModel>.Range(r => r.Field(p => p.Selling_price).LessThanOrEquals(upperLimit));
}
//検索条件をセット
search.Query(q => q.Bool(b => b.Must(condition)));
// 検索結果をリストにセット
try
{
var response = elasticClient.Search<SearchModel>(search);
foreach (var hit in response.Hits)
{
hits.Add(hit.Source);
}
}
catch
{
return null;
}
model.ResultItems = hits;
return PartialView("_SearchResult", model);
}