質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Elasticsearch

Elasticsearchは、クラウド向けに構築された、RESTful な API を提供する分散型のサーチエンジンアプリケーションです。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

4374閲覧

C#で Elasticsearch(NEST) の複数条件を動的に検索する方法がわからない

kuuman

総合スコア12

Elasticsearch

Elasticsearchは、クラウド向けに構築された、RESTful な API を提供する分散型のサーチエンジンアプリケーションです。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

1グッド

2クリップ

投稿2019/04/25 01:31

やりたいこと

C# で検索条件を動的に生成し、ElasticSearch で検索したいです。
特に、AND OR の組み合わせで複雑な検索条件を作りたいと考えています。

環境

Elasticsearch Version:6.6.1
NEST:6.0.0.0
開発言語:C#
開発環境:Visual Sutdio 2017、.NET Framework 4.6.1

現状

下記のコードで試しています。

C#

1using System; 2using System.Collections.Generic; 3using System.Linq; 4using Elasticsearch.Net; 5using Nest; 6 7namespace ConsoleApp1 8{ 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 var settings = new ConnectionSettings(new Uri("http://hoge:9200")); 14 var client = new ElasticClient(settings.DefaultIndex("hoge")); 15 16 IList<Report> hits = new List<Report>(); 17 var search = new SearchDescriptor<Report>(); 18 search.Type("hoge"); 19 search.Size(100); 20 QueryContainer condition; 21 22 // 検索文字の作成 23 var t1 = Query<Report>.Term(p => p.ttitle, "検索文字1"); 24 var t2 = Query<Report>.Term(p => p.ttitle, "検索文字2"); 25 26 // ここで複数条件を AND 又は OR でくっつけているのですが 27 // AND の場合うまく出力結果が出ない 28 // OR (condition = t1 || t2) の場合は結果が出る。 29 condition = t1 && t2; 30 31 search.Query(q => q.Bool(b => b.Must(conditon))); 32 33 try 34 { 35 var response = client.Search<Report>(search); 36 37 foreach(var hit in response.Hits) 38 { 39 hits.Add(hit.Source); 40 Console.WriteLine("id:" + hit.Source.id); 41 Console.WriteLine("タイトル:" + hit.Source.ttitle); 42 } 43 } 44 catch(Exception ex) 45 { 46 Console.WriteLine(ex.Message); 47 } 48 49 Console.WriteLine("検索結果:" + hits.Count); 50 Console.WriteLine("何かキーを押してください"); 51 Console.ReadKey(); 52 } 53 } 54 55 public class Report 56 { 57 public DateTime timestamp { get; set; } 58 public string version { get; set; } 59 public int id { get; set; } 60 public string ttitle { get; set; } 61 } 62 63}

JSON ではこのような検索をしたいと思っています。

JSON

1GET /hoge/_search 2{ 3 "query": { 4 "bool":{ 5 "must":[ 6 { 7 "term":{ 8 "ttitle": { 9 "value":"検索文字1" 10 } 11 } 12 }, 13 { 14 "term": { 15 "ttitle": { 16 "value": "検索文字2" 17 } 18 } 19 } 20 ] 21 } 22 } 23}
hihijiji👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

自己解決できました。
search.Query() 部分で2重に Must していたことが原因の様です。
Query を && で連結することで、すでに Must がつけられるようです。

C#

1using System; 2using System.Collections.Generic; 3using System.Linq; 4using Elasticsearch.Net; 5using Nest; 6 7namespace ConsoleApp1 8{ 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 var settings = new ConnectionSettings(new Uri("http://hoge:9200")); 14 var client = new ElasticClient(settings.DefaultIndex("hoge")); 15 16 IList<Report> hits = new List<Report>(); 17 var search = new SearchDescriptor<Report>(); 18 search.Type("hoge"); 19 search.Size(100); 20 QueryContainer condition; 21 22 // 検索文字の作成 23 var t1 = Query<Report>.Term(p => p.ttitle, "検索文字1"); 24 var t2 = Query<Report>.Term(p => p.ttitle, "検索文字2"); 25 26 // ここで複数条件を AND 又は OR でくっつけているのですが 27 // AND の場合うまく出力結果が出ない 28 // OR (condition = t1 || t2) の場合は結果が出る。 29 condition = t1 && t2; 30 31 // ★★ここを修正★★ 32 // q.bool(b => b.Must(conditon))) にすることで 33 // 二重に bool Must がかかった状態になっていた 34 //search.Query(q => q.Bool(b => b.Must(conditon))); 35 search.Query(q => conditon); 36 37 try 38 { 39 var response = client.Search<Report>(search); 40 41 foreach(var hit in response.Hits) 42 { 43 hits.Add(hit.Source); 44 Console.WriteLine("id:" + hit.Source.id); 45 Console.WriteLine("タイトル:" + hit.Source.ttitle); 46 } 47 } 48 catch(Exception ex) 49 { 50 Console.WriteLine(ex.Message); 51 } 52 53 Console.WriteLine("検索結果:" + hits.Count); 54 Console.WriteLine("何かキーを押してください"); 55 Console.ReadKey(); 56 } 57 } 58 59 public class Report 60 { 61 public DateTime timestamp { get; set; } 62 public string version { get; set; } 63 public int id { get; set; } 64 public string ttitle { get; set; } 65 } 66 67}

下記間違えていたJSON

JSON

1GET /hoge/_search 2{ 3 "query":{ 4 "bool":{ 5 "must":[ 6 { 7 "bool":{ 8 "must":[ 9 { 10 "term":{ 11 "ttitle":{"value":"検索文字1" 12 } 13 } 14 }, 15 { 16 "term":{ 17 "ttitle":{"value":"検索文字2" 18 } 19 } 20 } 21 ] 22 } 23 } 24 ] 25 } 26 }, 27 "size":100 28}

投稿2019/05/14 02:46

kuuman

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

手元の環境(7.0.0)では、上のような書き方でand条件のクエリが投げられたので・・・
まず、Elasticsearchに投げているクエリをデバッグで確認してみてはいかがでしょうか。

Csharp

1 2//デバッグ出力を可能に 3var client = new ElasticClient(settings.DefaultIndex("******").DisableDirectStreaming()); 4 5//中略 6var response = client.Search<*****>(search); 7Console.WriteLine(response.DebugInformation); 8

この中で、リクエストで投げているjsonが表示されるので、そこで期待しているjsonとどこがどう違うのか? を確認してみるのはどうでしょうか?

投稿2019/04/27 15:32

tsgkdt

総合スコア83

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kuuman

2019/04/28 01:42

ごかいとうありがとうございます。 たしかに、期待しているJSONができるかもわかっていませんでした。 かくにんしてみます。
kuuman

2019/05/14 02:47

解決することができました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問