Java での ElasticSearch の一部の API 実装

すべてをクエリする

指定されたインデックス ライブラリ内の指定されたタイプのドキュメントをクエリします。(この方法を使うと)

{
    
    
	"query": {
    
    
		"match_all": {
    
    }
	},
	"_source" : ["name","studymodel"]
}

_source: ソース フィルター設定。結果にどのフィールドが含まれるかを指定します。

結果の説明:

かかった時間: この操作にかかった時間 (ミリ秒単位)。

timed_out: リクエストがタイムアウトしたかどうか

_shards: この操作でどのシャードが検索されたかを示します

ヒット数: 検索でヒットしたレコード

Hist.total : 条件に一致するドキュメントの総数

Hist.hits : 一致度の高い上位 N 個のドキュメント

Hist.max_score: ドキュメント一致スコア。これが最高スコアです。

_score: 各ドキュメントには、降順に並べ替えられた一致スコアがあります。

_source: ドキュメントの元のコンテンツを表示します。

Javaクライアント

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestDSL {
    
    

    @Autowired
    RestHighLevelClient restHighLevelClient;

    @Autowired
    RestClient restClient;

    //全部搜索
    @Test
    public void testSearchAll() throws IOException {
    
    
        //创建搜索对象
        SearchRequest searchRequest = new SearchRequest("xc_course");
        //指定类型
        searchRequest.types("doc");
        //创建搜索源对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //搜索方式 搜索全部
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        //设置源字段过滤 第一个参数是包括哪些字段,第二个参数是不包括哪些字段
        searchSourceBuilder.fetchSource(new String[]{
    
    "name","studymodel"},new String[]{
    
    });
        //向搜索对象中设置搜索源
        searchRequest.source(searchSourceBuilder);
        //执行搜索
        SearchResponse response = restHighLevelClient.search(searchRequest);
        //搜索结果
        SearchHits hits = response.getHits();
        //匹配的总记录数
        long totalHits = hits.totalHits;
        //得到匹配度最高的文档
        SearchHit[] hitsHits = hits.getHits();
        for (SearchHit hit : hitsHits){
    
    
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            System.out.println(sourceAsMap);
        }
    }
}

ページングクエリ

ES は、from と size の 2 つのパラメータを渡すページング クエリをサポートしています。

form: 0 から始まる開始ドキュメントの添え字を示します。

size: クエリするドキュメントの数。

{
    
     "
	from" : 0, "size" : 1,
	"query": {
    
    
		"match_all": {
    
    }
	},
	"_source" : ["name","studymodel"]
}

Javaクライアント

SearchRequest searchRequest = new SearchRequest("xc_course");
searchRequest.types("xc_course");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//分页查询,设置起始下标,从0开始
searchSourceBuilder.from(0);
//每页显示个数
searchSourceBuilder.size(10);
//source源字段过虑
searchSourceBuilder.fetchSource(new String[]{
    
    "name","studymodel"}, new String[]{
    
    });
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);

用語クエリ

用語クエリは完全一致クエリで、検索時にキーワード全体が一致し、キーワードを単語に分割しません。

{
    
    
	"query": {
    
    
		"term" : {
    
    
			"name": "spring"
		}
	},
	"_source" : ["name","studymodel"]
}

上記の検索では、名前に「spring」という単語が含まれるドキュメントが検索されます。

Javaクライアント

SearchRequest searchRequest = new SearchRequest("xc_course");
searchRequest.types("xc_course");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery("name","spring"));
//source源字段过虑
searchSourceBuilder.fetchSource(new String[]{
    
    "name","studymodel"}, new String[]{
    
    });
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);

IDによる完全一致

ES は、複数の ID 値に基づいて照合する方法を提供します。

{
    
    
	"query": {
    
    
		"ids" : {
    
    
			"type" : "doc",
			"values" : ["3", "4", "100"]
		}
	}
}

Javaクライアント

String[] split = new String[]{
    
    "1","2"};
List<String> idList = Arrays.asList(split);
searchSourceBuilder.query(QueryBuilders.termsQuery("_id", idList));

照合クエリ

1. 基本的な使い方

matchクエリは全文検索で、検索文字列を単語に分割し、各エントリを用いてインデックスから検索する検索方法です。

一致クエリと用語クエリの違いは、一致クエリでは、検索前にまず検索キーワードを単語に分割し、次に各単語を使用してインデックス内を検索することです。

{
    
    
	"query": {
    
    
		"match" : {
    
    
			"description" : {
    
    
				"query" : "spring开发",
				"operator" : "or"
			}
		}
	}
}

query: 検索するキーワード。英語キーワードの場合は複数の単語を半角カンマで区切る必要がありますが、中国語キーワードの場合はカンマ区切りでもしなくても構いません。

演算子: or は、文書内に 1 つの単語が出現する限り条件が満たされることを意味し、文書内にすべての単語が出現する場合にのみ条件が満たされることを意味します。

上記の検索の実行プロセスは次のとおりです。

1.「春の発展」を春と発展の2つの言葉に分ける

2. 次に、Spring と Development という 2 つの単語を使用して、一致するインデックスを検索します。

3. 演算子が or に設定されているため、1 つの単語が正常に一致する限り、ドキュメントが返されます。

Javaクライアント

//根据关键字搜索
@Test
public void testMatchQuery() throws IOException {
    
    
	SearchRequest searchRequest = new SearchRequest("xc_course");
	searchRequest.types("xc_course");
	SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
	//source源字段过虑
	searchSourceBuilder.fetchSource(new String[]{
    
    "name","studymodel"}, new String[]{
    
    });
	//匹配关键字
	searchSourceBuilder.query(QueryBuilders.matchQuery("description", "spring开发").operator(Operator.OR));
	searchRequest.source(searchSourceBuilder);
	SearchResponse searchResponse = client.search(searchRequest);
	SearchHits hits = searchResponse.getHits();
	SearchHit[] searchHits = hits.getHits();
	for (SearchHit hit : searchHits) {
    
    
		String index = hit.getIndex();
		String type = hit.getType();
		String id = hit.getId();
		float score = hit.getScore();
		String sourceAsString = hit.getSourceAsString();
		Map<String, Object> sourceAsMap = hit.getSourceAsMap();
		String name = (String) sourceAsMap.get("name");
		String studymodel = (String) sourceAsMap.get("studymodel");
        String description = (String) sourceAsMap.get("description");
        System.out.println(name);
        System.out.println(studymodel);
        System.out.println(description);
	}
}

2、最小一致が必要

上記で使用されている演算子 = は、1 つの単語が一致する限りスコアが加算されることを意味します。少なくとも 2 つの単語が 3 つの単語と一致する場合、どうすればスコアが得られますか?

minimum_Should_match を使用して、ドキュメントに一致する単語の割合を指定します。

たとえば、検索ステートメントは次のようになります。

{
    
    
	"query": {
    
    
		"match" : {
    
    
        "description" : {
    
    
        	"query" : "spring开发框架",
        	"minimum_should_match": "80%"
       		}
        }
    }
}

「スプリング開発フレームワーク」は、スプリング、開発、フレームワークの 3 つの単語に分割されます。

"minimum_Should_match": "80%" を設定すると、ドキュメント内の 3 つの単語の一致率が 80%、つまり 3*0.8=2.4 (四捨五入されて 2) であることを意味し、少なくとも 2 つの単語が正常に一致する必要があることを示します。文書の中で。

Javaクライアント

//匹配关键字
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("description", "前台页面开发框架 架构").minimumShouldMatch("80%");//设置匹配占比
searchSourceBuilder.query(matchQueryBuilder);

マルチクエリ

上で学習した termQuery と matchQuery は一度に 1 つのフィールドのみと一致しますが、このセクションでは一度に複数のフィールドと一致できる multiQuery について学習します。

1. 単一アイテム マッチングの基本的な使用法は 1 つのフィールドでのマッチングであり、複数アイテム マッチングの基本的な使用法は、キーワードを使用して複数のフィールドでマッチングすることです。

キーワード「spring css」を使用して、名前フィールドと説明フィールドを照合します。

{
    
    
    "query": {
    
    
        "multi_match" : {
    
    
            "query" : "spring css",
            "minimum_should_match": "50%",
            "fields": [ "name", "description" ]
    	}
    }
}

2.ブーストブースト

複数のフィールドを一致させる場合、フィールドのブースト (重み) を増やしてスコアを向上させることができます

ブーストブースト。通常、名前に一致するキーワードの重みは、説明に一致する重みよりも高くなります。ここでは、名前の重みを増やすことができます。

{
    
    
	"query": {
    
    
		"multi_match" : {
    
    
            "query" : "spring框架",
            "minimum_should_match": "50%",
            "fields": [ "name^10", "description" ]
		}
	}
}

「name^10」は重みを10倍にすることを意味し、上記のクエリを実行すると名前にspringキーワードを含む文書が1位となることが分かる。

Javaクライアント

MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("spring框架",
"name", "description").minimumShouldMatch("50%");
multiMatchQueryBuilder.field("name",10);//提升boost

ブールクエリ

ブールクエリは、複数のクエリの組み合わせを実現する Lucene の BooleanQuery クエリに相当します。

3 つのパラメータ:

  • must: ドキュメントは、must に含まれるクエリ条件と一致する必要があります。これは「AND」と同等です。
  • should: ドキュメントは should に含まれる 1 つ以上のクエリ条件に一致する必要があります。これは「OR」に相当します。
  • must_not: ドキュメントは、must_not に含まれるクエリ条件と一致できません。これは「NOT」に相当します。

以下のクエリをテストするには、must、 should、must_not を使用します。

{
    
    
    "_source" : [ "name", "studymodel", "description"],
    "from" : 0, "size" : 1,
        "query": {
    
    
            "bool" : {
    
    
            "must":[
                {
    
    
                    "multi_match" : {
    
    
                        "query" : "spring框架",
                        "minimum_should_match": "50%",
                        "fields": [ "name^10", "description" ]
                    }
                },
                {
    
    
                    "term":{
    
    
                    	"studymodel" : "201001"
                    }
                }
            ]
        }
    }
}

must: 必ず、複数のクエリ条件が満たされなければならないことを意味します。(通常はmustを使用します)

should: 複数のクエリ条件の 1 つが満たされる限り、またはを示します。

must_not: しないことを意味します。

Javaクライアント

//BoolQuery,将搜索关键字分词,拿分词去索引库搜索
@Test
public void testBoolQuery() throws IOException {
    
    
	//创建搜索请求对象
	SearchRequest searchRequest= new SearchRequest("xc_course");
	searchRequest.types("doc");
	//创建搜索源配置对象
	SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
	searchSourceBuilder.fetchSource(new String[]{
    
    "name","pic","studymodel"},new String[]{
    
    });
	//multiQuery
	String keyword = "spring开发框架";
	MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("spring框架",
	"name", "description").minimumShouldMatch("50%");
	multiMatchQueryBuilder.field("name",10);
	//TermQuery
	TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("studymodel", "201001");
	//布尔查询
	BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
	boolQueryBuilder.must(multiMatchQueryBuilder);
	boolQueryBuilder.must(termQueryBuilder);
	//设置布尔查询对象
	searchSourceBuilder.query(boolQueryBuilder);
	searchRequest.source(searchSourceBuilder);//设置搜索源配置
	SearchResponse searchResponse = client.search(searchRequest);
	SearchHits hits = searchResponse.getHits();
	SearchHit[] searchHits = hits.getHits();
	for(SearchHit hit:searchHits){
    
    
		Map<String, Object> sourceAsMap = hit.getSourceAsMap();
		System.out.println(sourceAsMap);
	}
}

フィルター

フィルタリングとは、検索結果をフィルタリングすることですが、フィルタは主に文書が一致するかどうかを判断するものであり、文書の一致スコアを計算して判断するものではないため、クエリよりもフィルタの性能が高く、検索に便利です。キャッシュ。クエリまたはフィルタとクエリを組み合わせて、できる限りフィルタを使用することをお勧めします。

フィルターはブール クエリで使用され、次のフィルターは検索結果に基づきます。

{
    
    
	"_source": ["name", "studymodel", "description", "price"],
	"query": {
    
    
		"bool": {
    
    
			"must": [{
    
    
				"multi_match": {
    
    
					"query": "spring框架",
					"minimum_should_match": "50%",
					"fields": ["name^10", "description"]
				}
			}],
			"filter": [{
    
    
					"term": {
    
    
						"studymodel": "201001"
					}
				},
				{
    
    
					"range": {
    
    
						"price": {
    
    
							"gte": 60,
							"lte": 100
						}
					}
				}
			]
		}
	}
}

range: 範囲フィルタリング。60 以上 100 以下のレコードを保持します。

term: 項目一致フィルタリング。スタディモデルが「201001」に等しいレコードを保持します。

注: range と term は一度に 1 つのフィールドのみをフィルターできます。

Javaクライアント

//布尔查询使用过虑器
@Test
public void testFilter() throws IOException {
    
    
    SearchRequest searchRequest = new SearchRequest("xc_course");
    searchRequest.types("doc");
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    //source源字段过虑
    searchSourceBuilder.fetchSource(new String[]{
    
    "name","studymodel","price","description"},
    new String[]{
    
    });
    searchRequest.source(searchSourceBuilder);
    //匹配关键字
    MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("spring框
    架", "name", "description");
    //设置匹配占比
    multiMatchQueryBuilder.minimumShouldMatch("50%");
    //提升另个字段的Boost值
    multiMatchQueryBuilder.field("name",10);
    searchSourceBuilder.query(multiMatchQueryBuilder);
    //布尔查询
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    boolQueryBuilder.must(searchSourceBuilder.query());
    //过虑
    boolQueryBuilder.filter(QueryBuilders.termQuery("studymodel", "201001"));
    boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(60).lte(100));
    SearchResponse searchResponse = client.search(searchRequest);
    SearchHits hits = searchResponse.getHits();
    SearchHit[] searchHits = hits.getHits();
    for (SearchHit hit : searchHits) {
    
    
        String index = hit.getIndex();
        String type = hit.getType();
        String id = hit.getId();
        float score = hit.getScore();
        String sourceAsString = hit.getSourceAsString();
        Map<String, Object> sourceAsMap = hit.getSourceAsMap();
        String name = (String) sourceAsMap.get("name");
        String studymodel = (String) sourceAsMap.get("studymodel");
        String description = (String) sourceAsMap.get("description");
        System.out.println(name);
        System.out.println(studymodel);
        System.out.println(description);
    }
}

分類する

フィールドには 1 つ以上の並べ替えを追加でき、キーワード、日付、浮動小数点数などのタイプの追加がサポートされています。テキスト タイプのフィールドに並べ替えを追加することはできません。

POST を http://localhost:9200/xc_course/doc/_search に送信します

0 ~ 100 元の価格範囲でドキュメントをフィルターし、最初にスタディモデルの降順、次に価格の昇順で結果を並べ替えます。

{
    
    
	"_source": ["name", "studymodel", "description", "price"],
	"query": {
    
    
		"bool": {
    
    
			"filter": [{
    
    
				"range": {
    
    
					"price": {
    
    
						"gte": 0,
						"lte": 100
					}
				}
			}]
		}
	},
	"sort": [{
    
    
			"studymodel": "desc"
		},
		{
    
    
			"price": "asc"
		}
	]
}

Javaクライアント



ハイライト

強調表示により、検索結果内の 1 つ以上の単語を強調表示して、一致するキーワードの場所をユーザーに示すことができます。

これは、次のように検索ステートメントにハイライトを追加することで実現できます。

{
    
    
	"_source": ["name", "studymodel", "description", "price"],
	"query": {
    
    
		"bool": {
    
    
			"must": [{
    
    
				"multi_match": {
    
    
					"query": "开发框架",
					"minimum_should_match": "50%",
					"fields": ["name^10", "description"],
					"type": "best_fields"
				}
			}],
			"filter": [{
    
    
				"range": {
    
    
					"price": {
    
    
						"gte": 0,
						"lte": 100
					}
				}
			}]
		}
	},
	"sort": [{
    
    
		"price": "asc"
	}],
	"highlight": {
    
    
		"pre_tags": ["<tag>"],
		"post_tags": ["</tag>"],
		"fields": {
    
    
			"name": {
    
    },
			"description": {
    
    }
		}
	}
}

Javaクライアント

@Test
public void testHighlight() throws IOException {
    
    
    SearchRequest searchRequest = new SearchRequest("xc_course");
    searchRequest.types("doc");
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    //source源字段过虑
    searchSourceBuilder.fetchSource(new String[]{
    
    "name","studymodel","price","description"},
    new String[]{
    
    });
    searchRequest.source(searchSourceBuilder);
    //匹配关键字
    MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("开发",
    "name", "description");
    searchSourceBuilder.query(multiMatchQueryBuilder);
    //布尔查询
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    boolQueryBuilder.must(searchSourceBuilder.query());
    //过虑
    boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(0).lte(100));
    //排序
    searchSourceBuilder.sort(new FieldSortBuilder("studymodel").order(SortOrder.DESC));
    searchSourceBuilder.sort(new FieldSortBuilder("price").order(SortOrder.ASC));
    //高亮设置
    HighlightBuilder highlightBuilder = new HighlightBuilder();
    highlightBuilder.preTags("<tag>");//设置前缀
    highlightBuilder.postTags("</tag>");//设置后缀
    // 设置高亮字段
    highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
    // highlightBuilder.fields().add(new HighlightBuilder.Field("description"));
    searchSourceBuilder.highlighter(highlightBuilder);
    SearchResponse searchResponse = client.search(searchRequest);
    SearchHits hits = searchResponse.getHits();
    SearchHit[] searchHits = hits.getHits();
    for (SearchHit hit : searchHits) {
    
    
        Map<String, Object> sourceAsMap = hit.getSourceAsMap();
        //名称
        String name = (String) sourceAsMap.get("name");
        //取出高亮字段内容
        Map<String, HighlightField> highlightFields = hit.getHighlightFields();
        if(highlightFields!=null){
    
    
            HighlightField nameField = highlightFields.get("name");
            if(nameField!=null){
    
    
                Text[] fragments = nameField.getFragments();
                StringBuffer stringBuffer = new StringBuffer();
                for (Text str : fragments) {
    
    
                    stringBuffer.append(str.string());
                } 
                name = stringBuffer.toString();
            }
        } 
        String index = hit.getIndex();
        String type = hit.getType();
        String id = hit.getId();
        float score = hit.getScore();
        String sourceAsString = hit.getSourceAsString();
        String studymodel = (String) sourceAsMap.get("studymodel");
        String description = (String) sourceAsMap.get("description");
        System.out.println(name);
        System.out.println(studymodel);
        System.out.println(description);
    }
}

おすすめ

転載: blog.csdn.net/weixin_43650254/article/details/100902304