美文网首页
简明Elasticsearch使用教程

简明Elasticsearch使用教程

作者: AlienPaul | 来源:发表于2018-12-04 21:20 被阅读0次

    Elasticsearch安装和配置问题

    启动时候报错的问题

    max file descriptors [4096] for elasticsearch process likely too low, increase to at least [65536]

    max number of threads [1024] for user [lishang] likely too low, increase to at least [2048]

    max number of threads [1024] for user [lish] likely too low, increase to at least [2048]

    解决方案:

    切换root用户修改/etc/security/limits.conf

    添加如下内容:

    * soft nofile 65536
    
    * hard nofile 131072
    
    * soft nproc 2048
    
    * hard nproc 4096
    

    修改/etc/systemctl.conf

    添加如下配置:

    vm.max_map_count=655360
    

    接下来执行命令:

    sysctl -p
    

    即可解决启动报错问题。

    无法以root用户启动

    Elasticsearch默认不建议用户使用root用户运行。如果需要使用root账户可以使用以下启动脚本:

    ./elasticsearch -Des.insecure.allow.root=true
    

    Elasticsearch HTTP操作

    基本增删改查

    获取一个document

    curl -X GET http://localhost:9200/index/type/id
    

    获取同一type的所有元素

    curl -X GET http://localhost:9200/index/type/_search
    

    新增一个document

    可以使用POST或PUT请求。

    curl -X POST http://localhost:9200/index/type/id -d '
    {
        "field": "value",
        ...
    }
    '
    

    修改一个document

    可以使用POST或PUT请求。

    curl -X PUT http://localhost:9200/index/type/id -d '
    {
        "field": "value",
        ...
    }
    '
    

    删除一个document

    curl -X DELETE http://localhost:9200/index/type/id
    

    检索操作

    基本语法如下:

    curl -X POST http://localhost:9200/index/type/_search -d '
    {
        "query": {
            ...
        }
    }
    '
    

    match_all

    匹配所有的文档

    {
        "query": {
            "match_all": {}
        }
    }
    

    match_none

    和match_all相反,不匹配任何文档

    {
        "query": {
            "match_none": {}
        }
    }
    

    match

    {
        "query": {
            "match": {
                "message": "hello world"
            }
        }
    }
    

    match中检索的文本会被分词。默认来说分词后各个词组间的关系为or。该例子为查找出message字段包含hello或world的文档。

    {
        "query": {
            "match" : {
                "message" : {
                    "query" : "this is a test",
                    "operator" : "and"
                }
            }
        }
    }
    

    通过增加operator参数,可以把默认的or关系修改为and。

    match_phrase

    {
        "query": {
            "match_phrase": {
                "name": "软件公司"
            }
        }
    }
    

    匹配的文档要求“软件公司”这四个字必须都出现,且按照顺序出现。

    {
        "query": {
            "match_phrase": {
                "name": {
                    "query": "软件公司",
                    "slop": 1
                }
            }
        }
    }
    

    slop用来指定各个分词匹配时的最大间隔,即“软件X公司”也会被匹配。

    多字段匹配

    {
      "query": {
        "multi_match" : {
          "query": "this is a test",
          "fields": [ "subject", "message" ] 
        }
      }
    }
    

    分别用"subject"和"message"字段内容匹配"this is a test",如果任意一个字段匹配,该文档会出现在检索结果中。

    匹配的fields也可以使用星号作为通配符。

    {
      "query": {
        "multi_match" : {
          "query": "Will Smith",
          "fields": [ "title", "*_name" ] 
        }
      }
    }
    

    查询title和以名称以_name结尾的字段。

    {
      "query": {
        "multi_match" : {
          "query" : "this is a test",
          "fields" : [ "subject^3", "message" ] 
        }
      }
    }
    

    提升subject的score权重(3倍于message)。

    term

    term查询关键字不进行分词处理。

    官方文档原文描述如下:

    The term query finds documents that contain the exact term specified in the inverted index.

    {
        "query": {
            "term": {
                "message": "some text"
            }
        }
    }
    

    term的查询结果还与文档是否分词有关。如果文档内容不分词,大致相当于SQL中的"="。

    match和term的区别为:如果文档的有关字段进行了分词,match是搜索关键字的分词和文档字段的分词逐个比较,而term则是搜索关键字不分词,整个和文档字段的分词进行比较。

    terms

    {
        "query": {
            "terms" : { "message" : ["some", "text"]}
        }
    }
    

    查找message字段包含some或text的文档。

    Query String 查询

    {
        "query": {
            "query_string" : {
                "default_field" : "content",
                "query" : "(new york city) OR (big apple)"
            }
        }
    }
    

    new york citybig apple分别交给分词器处理。

    Range Query

    范围查询

    {
        "query": {
            "range" : {
                "age" : {
                    "gte" : 10,
                    "lte" : 20,
                    "boost" : 2.0
                }
            }
        }
    }
    

    可以使用的参数有:

    • gt: greater than
    • gte: greater than or equals
    • lt: less than
    • lte: less than or equals

    Exists

    字段存在查询

    {
        "query": {
            "exists" : { "field" : "user" }
        }
    }
    

    文档中user字段的值不能为null,user字段必须要存在。

    Prefix

    前缀查询

    {
        "query": {
            "prefix" : { "user" : "pe" }
        }
    }
    

    查找user字段以pe开头的文档(搜索关键字不分词)

    wildcard

    通配符查询

    {
        "query": {
            "wildcard" : { "user" : "pa*l" }
        }
    }
    

    可以匹配paul或paal等。为了保证性能,最好不要在开头使用通配符(比如匹配*aul)。
    通配符说明:

    • 星号(*)匹配0个或多个字符
    • 问号(?)匹配任意单个字符

    中英文单字(字母)匹配场景

    中文模糊搜索

    {
        "query": {
            "match_phrase": {
                "name": "公司"
            }
        }
    }
    

    match_phrase 的意思为短语匹配,不仅要匹配短语的字,而且这些字出现的顺序也必须要匹配

    英文按字母模糊搜索

    {
        "query": {
            "wildcard": {
                "name": "*aster*"
            }
        }
    }
    

    布尔组合条件搜索

    通过bool组合查询我们可以实现多个查询条件间andor逻辑组合关系。例如:

    {
        "query": {
            "bool": {
                "should": [
                    {
                        "wildcard": {
                            "name": "*aster*"
                        }
                        
                    }, {
                        "match_phrase": {
                            "authorList.name": "张"
                        }
                    }
                ]
                
            }
        }
    }
    

    bool组合查询内有多种子句:

    • must 子句中的所有匹配必须都满足。
    • must_not 和must相反,子句中的所有匹配必须都不满足。
    • should 相当于或的关系,子句中的匹配只要至少有一个满足。如果存在must或filter子句,should中的条件默认不要求至少满足一个,即仅匹配must或filter子句且should中一个条件都不满足的文档也会被检索出来。如需设置至少满足的should条件个数,可以添加minimum_should_match参数。
    • filter 和must类似,不同的是搜索结果的匹配度评分会被忽略。

    minimum_should_match示例:

    {
        "query": {
            "bool": {
                "should": [
                    {
                        "wildcard": {
                            "fieldList.fieldName": "*?0*"
                        }
                    },
                    {
                        "match_phrase": {
                            "fieldName.fieldComments": "?0"
                        }
                    }
                ],
                "filter": [
                    {
                        "term": {
                            "systemId": "?1"
                        }
                    }
                ],
                "minimum_should_match": 1
            }
        }
    }
    

    以上查询不仅要求filter语句满足,而且should中的条件至少要满足一个。

    Bool查询更详细的用法请参考:
    https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html

    嵌套对象字段的查询

    {
        "query": {
            "match_phrase": {
                "author.name": "Paul Jackson"
            }
        }
    }
    

    检索出author对象中的name字段值为Paul Jackson的文档。

    SpringBoot 整合Elasticsearch

    SpringBoot 官方以为我们做好了elasticsearch的整合。对于常见的操作,我们不必再去编写json请求报文。

    SpringBoot和elasticsearch官方starter名为:springboot starter data elasticsearch。下面是这个starter的使用方法。

    加入依赖

    pom.xml加入依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    

    注意:
    Elasticsearch服务端版本号最好和springboot中依赖的elasticsearch.jar版本一致。
    elasticsearch.jar的版本号可以通过查看项目依赖关系图得知。

    建立Data Class

    以Book这个类为例(使用了Project lombok)

    Book.java:

    @Document(indexName = "database", type = "book")
    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    public class Book {
        private Long id;
    
        private String name;
    
        private List<Author> authorList; //支持嵌套元素
    }
    

    Author.class

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Author {
        private String name;
    }
    

    使用@Document注解来表示该bean是ES的文档,indexName为索引名称,type为索引类型。

    注:可以使用@Field注解来修改字段默认的属性,比如是否索引,是否储存,使用什么分词器等。

    建立Repository

    public interface BookRepo extends ElasticsearchCrudRepository<Book, Long> {
        // 解析方法名方式
        List<Book> findAllByNameContains(String name);
        
        // 自定义Query JSON方式
        @Query("{\"bool\":{\"must\":[{\"match_phrase\":{\"authorList.name\":\"?0\"}}]}}")
        List<Book> matchPhrase(String phrase);
    }
    

    Repository需要继承ElasticsearchCrudRepository<T, ID>接口。

    Repository自定义方法命名规则和Spring Data JPA用法完全一致。同样可以加入Pageable参数实现分页查询。
    可以使用@Query注解来自定义查询。


    除此之外也可以通过NativeSearchQueryBuilder的方式来查询elasticsearch。

    代码如下:

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    
    @Test
    public void nativeQueryBuilderTest() {
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
        .withQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchPhraseQuery("authorList.name", "张三")))
        .build();
        List<Book> bookList = elasticsearchTemplate.queryForList(searchQuery, Book.class);
        System.out.println(bookList);
    }
    

    我们使用QueryBuilders类来构造各种查询参数。

    返回分页数据的例子:

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    
    @Test
    public void nativeQueryBuilderTest() {
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().
                withQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchPhraseQuery("authorList.name", "张三")))
                .withPageable(PageRequest.of(0, 20)) //加上分页参数
                .build();
        Page<Book> books = elasticsearchTemplate.queryForPage(searchQuery, Book.class); //获取Page类型结果
        System.out.println(books.getContent());
    }
    

    参考文档

    Elasticsearch 官方文档: https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

    SpringBoot starter data elasticsearch官方文档: https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/

    相关文章

      网友评论

          本文标题:简明Elasticsearch使用教程

          本文链接:https://www.haomeiwen.com/subject/hpmvcqtx.html