LoginSignup
2

More than 5 years have passed since last update.

Elasticsearch.Netで検索条件を動的に生成

Last updated at Posted at 2017-11-28

開発メモ

 環境: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);
        }

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2