Elasticsearch基础查询

Elasticsearch基础查询

  • 一、简介说明

    注意:以下命令都是使用sense测试(ElasticSearch第二步-CRUD之Sense),且数据都已经使用过IK分词。

    以下测试数据来源于文档(db_test/person)

    需要注意的是下面的id是文档的ID,不是elasticsearch生成的_id,删除文档需要用_id

    复制代码
    { "id": "0959ab1c-47bf-4417-904c-e5bc774ce730", "name": "王军华", "age": 265, "sex": true, "birthday": "2015-04-07T18:11:35.2655732+08:00", "intro":"介绍" }
    复制代码

     

    注意:must和should并列,should无效


    二、各类查询示例


    查询所有索引库的数据

    POST /_search

     

    查询索引库db_test中的所有数据

    说明:db_test代表所有库(db)

    POST /db_test/_search

     

    查询索引库db_test表person中的所有的数据

    说明:db_test代表所有库(db),person代表文档

    POST /db_test/person/_search 

     

    查询索引库db_test表person中age=3的一条数据

    说明:db_test代表所有库(db),person代表文档



    POST /db_test/person/_search?q=age:3 //或者这样写(DSL写法) POST /db_test/person/_search { "query": { "query_string": { "fields": ["age"], "query": 3 } } }


    多字段单分词字段并且条件查询

    查询索引库db_test表person中age从500到800,intro包含"研究"的数据

    复制代码
    POST /db_test/person/_search
    { "query":{ "bool":{ "must":[
                    { "range":{ "age":{ "from":"500","to":"800" }
                        }                
                    },
                    { "term":{ "intro":"研究" }
                    }]
            }
        }
    }
    复制代码

     

    多字段多分词字段并且分词或者条件

    查询索引库db_test表person中age大于500,intro包含"研究"或者"方鸿渐"的数据

    复制代码
    POST /db_test/person/_search
    { "query":{ "bool":{ "must":[
                    { "range":{ "age":{ "gt":"500" }
                        }                
                    },
                    { "terms":{ "intro":["研究","方鸿渐"]
                        }
                    }]
            }
        }
    }
    复制代码

     

    分页/排序/高亮显示

    说明:size如果不写默认是10,from如果不写默认是0。取前20条数据,按照age升序,生日降序,并且北京高亮显示。

    复制代码
    POST /db_test/person/_search
    { "query": { "term":{"intro":"北京" }
        }, "from": 0, "size": 20, "sort":{ "age" : {"order" : "asc"}, "birthday": {"order" : "desc"}
            
        } , "highlight" : { "pre_tags" : ["<tag1>", "<tag2>"], "post_tags" : ["</tag1>", "</tag2>"], "fields" : { "intro" : {}
            }
        }
    }
    复制代码

     还可以这样写

    GET /_search?size=5 GET /_search?size=5&from=5 GET /_search?size=5&from=10

     

     

    单字段多分词或者关系查询

    说明:查询intro包含"研究"或者"方鸿渐"。

    (这在全文检索时非常有用)

    第一种写法:



    POST /db_test/person/_search { "query":{ "bool":{ "must":[ { "query_string":{ "default_field":"intro", "query":"研究方鸿渐" } } ] } }, "sort": [ { "birthday": { "order": "desc" } } ]}


    第二种写法:



    POST /db_test/person/_search { "query": { "query_string": { "fields": ["intro"], "query": "研究方鸿渐" } }, "sort": [ { "birthday": { "order": "asc" } } ] }



    第三种写法:



    POST /db_test/person/_search { "query":{ "bool":{ "should":[ { "term":{"intro":"研究"} }, { "term":{"intro":"方鸿渐"} } ] } }, "sort": [ { "birthday": { "order": "desc" } } ] }


    单字段多分词并且关系查询

     intro包含"研究""方鸿渐"的写法如下:



    POST /db_test/person/_search { "query":{ "bool":{ "must":[ { "term":{"intro":"研究"} }, { "term":{"intro":"方鸿渐"} } ] } } }


     

    多字段多分词 字段或者分词并且关系查询

    说明:查询 title中包含"朋友"并且包含"吃饭" 或者 content中包含"朋友"并且包含"吃饭"  title和content中只要有一个中包含"朋友"并且"吃饭"两个关键字就行

    复杂条件的范例-----------------------

    插入测试数据



    PUT /db_news/news/1 { "title":"我是中国人", "content":"我爱北京和天安门" } PUT /db_news/news/2 { "title":"我是中国人", "content":"朋友在一起就是亲家" } PUT /db_news/news/3 { "title":"亲家的朋友", "content":"我们明天去玩吧" } PUT /db_news/news/4 { "title":"朋友在一起吃饭", "content":"我们明天去玩吧" } PUT /db_news/news/5 { "title":"朋友在一起吃饭", "content":"亲家的朋友在一起吃饭" } PUT /db_news/news/6 { "title":"在阿萨德", "content":"亲家的在一起" } PUT /db_news/news/7 { "title":"在一起", "content":"按时到岗" } PUT /db_news/news/8 { "title":"在一起吃饭", "content":"朋友啊吃饭" } PUT /db_news/news/9 { "title":"在一起吃饭", "content":"朋友啊吃饭" }


    第一种写法


    POST /db_news/news/_search { "query":{ "bool":{ "should":[ { "bool": { "must":[ { "term":{"title":"朋友"} }, { "term":{"title":"吃饭"} } ] } } ], "should":[ { "bool": { "must":[ { "term":{"content":"朋友"} }, { "term":{"content":"吃饭"} } ] } } ] } } }


     第二种写法(参考http://www.elasticsearch.cn/guide/reference/query-dsl/query-string-query.html



    POST /db_news/news/_search { "query":{ "bool":{ "should":[ { "query_string":{ "default_field":"title", "query":"朋友吃饭", "default_operator":"AND", "analyzer":"ik" } }, { "query_string":{ "default_field":"content", "query":"朋友吃饭", "default_operator":"AND", "analyzer":"ik" } } ] } } }



    多字段多分词  字段或者分词或者关系查询

     查询 title中包含"朋友"或者包含"吃饭" 或者 content中包含"朋友"或者包含"吃饭"  也就是说只有title和content中包含"朋友"或者"吃饭"两个关键字就行

     第一种写法:



    POST /db_news/news/_search { "query":{ "bool":{ "should":[ { "term":{"title":"朋友"} }, { "term":{"title":"吃饭"} }, { "term":{"content":"朋友"} }, { "term":{"content":"吃饭"} } ] } } }


    第二种写法:



    POST /db_news/news/_search { "query":{ "bool":{ "should":[ { "terms":{"title":["朋友","吃饭"]} }, { "terms":{"content":["朋友","吃饭"]} } ] } } }


    第三种写法:(对于全文检索比较简单:比如招聘网站,搜索公司名或者职位名包含关键字asp.net 或者mvc这两个关键字任意一个)



    POST /db_news/news/_search { "query":{ "bool":{ "should":[ { "query_string":{ "default_field":"title", "query":"朋友吃饭" } }, { "query_string":{ "default_field":"content", "query":"朋友吃饭" } } ] } } }


     

    查询部分字段数据 

    说明:只查询age和intro

    POST /db_test/person/_search?_source=age,intro

    同时查询多个不同的文档

     插入测试数据



    PUT /db_news { "settings" : { "analysis" : { "analyzer" : { "stem" : { "tokenizer" : "standard", "filter" : ["standard", "lowercase", "stop", "porter_stem"] } } } }, "mappings" : { "news" : { "dynamic" : true, "properties" : { "title" : { "type" : "string", "indexAnalyzer" : "ik", "searchAnalyzer":"ik" }, "content" : { "type" : "string", "indexAnalyzer" : "ik", "searchAnalyzer":"ik" } } } } } PUT /db_news/news/1 { "title":"第一条新闻", "content":"我爱北京天安门" }


    测试查询

    复制代码
    GET /_mget
    { "docs" : [
          { "_index" : "db_news", "_type" : "news", "_id" : 1 },
          { "_index" : "db_test", "_type" : "person", "_id" : "5bd94e88-10cb-4e9f-9ba6-df8ff8b59081" }
       ]
    }
    复制代码

     

    查询包含一组id的文档集合

    GET /db_news/news/_mget
    { "ids" : [ "2", "1" ]
    }

    批量操作

    说明:可以批量添加数据,详情:http://es.xiaoleilu.com/030_Data/55_Bulk.html

    POST /_bulk
    { "create": { "_index": "db_news", "_type": "news", "_id": "3" }}
    { "title" : "john@smith.com", "content" : "John Smith" }
    { "create": { "_index": "db_news", "_type": "news", "_id": "4" }}
    { "title" : "john@smdsith.com", "content" : "John Smidth" }


Elasticsearch中文分词器IK配置

  • 一、简述示例

    elasticsearch官方只提供smartcn这个中文分词插件,效果不是很好,好在国内有medcl大神(国内最早研究es的人之一)写的两个中文分词插件,一个是ik的,一个是mmseg的,下面分别介绍ik的用法,

    当我们创建一个index(库db_news)时,easticsearch默认提供的分词器db_news,分词结果会把每个汉字分开,而不是我们想要的根据关键词来分词。例如:

    代码如下:

    GET /db_news/_analyze?analyzer=standard
    {
        我爱北京天安门
    }

    分词结果如下:

    复制代码
    { "tokens": [
          { "token": "我", "start_offset": 6, "end_offset": 7, "type": "<IDEOGRAPHIC>", "position": 1 },
          { "token": "爱", "start_offset": 7, "end_offset": 8, "type": "<IDEOGRAPHIC>", "position": 2 },
          { "token": "北", "start_offset": 8, "end_offset": 9, "type": "<IDEOGRAPHIC>", "position": 3 },
          { "token": "京", "start_offset": 9, "end_offset": 10, "type": "<IDEOGRAPHIC>", "position": 4 },
          { "token": "天", "start_offset": 10, "end_offset": 11, "type": "<IDEOGRAPHIC>", "position": 5 },
          { "token": "安", "start_offset": 11, "end_offset": 12, "type": "<IDEOGRAPHIC>", "position": 6 },
          { "token": "门", "start_offset": 12, "end_offset": 13, "type": "<IDEOGRAPHIC>", "position": 7 }
       ]
    }
    复制代码

     

    正常情况下,这不是我们想要的结果,比如我们更希望 “我”,“爱”,“北京”,"天安门"这样的分词,这样我们就需要安装中文分词插件,ik就是实现这个功能的。


     安装ik插件

     手动配置方式

    第一种方式是直接下载配置,这种方式比较麻烦(对于Windows用户来讲),这里我也不讲了

    下载地址:https://github.com/medcl/elasticsearch-analysis-ik

    直接使用RTF版本

    第二种方式是直接下载elasticsearch中文发行版。下载地址是:https://github.com/medcl/elasticsearch-rtf重新运行安装elasticsearch实例

    安装完毕,执行命令:

    GET /db_news/_analyze?analyzer=ik
    {
        我爱北京天安门啊王军华
        
    }

    结果如下:

    复制代码
    { "tokens": [
          { "token": "", "start_offset": 6, "end_offset": 7, "type": "CN_CHAR", "position": 1 },
          { "token": "", "start_offset": 7, "end_offset": 8, "type": "CN_CHAR", "position": 2 },
          { "token": "北京", "start_offset": 8, "end_offset": 10, "type": "CN_WORD", "position": 3 },
          { "token": "天安门", "start_offset": 10, "end_offset": 13, "type": "CN_WORD", "position": 4 },
          { "token": "", "start_offset": 13, "end_offset": 14, "type": "CN_CHAR", "position": 5 },
          { "token": "王军", "start_offset": 14, "end_offset": 16, "type": "CN_WORD", "position": 6 },
          { "token": "", "start_offset": 16, "end_offset": 17, "type": "CN_CHAR", "position": 7 }
       ]
    }
    复制代码

     

    关于分词器定义需要注意的地方

    如果我们直接创建索引库,会使用默认的分词进行分词,这不是我们想要的结果。这个时候我们再去更改分词器会报错如下:

    { "error": "IndexAlreadyExistsException[[db_news] already exists]", "status": 400 }

    而且没有办法解决冲突,唯一的办法是删除已经存在的索引,新建一个索引,并制定mapping使用新的分词器(注意要在数据插入之前,否则会使用elasticsearch默认的分词器)。

     新建索引命令如下:



    PUT /db_news { "settings" : { "analysis" : { "analyzer" : { "stem" : { "tokenizer" : "standard", "filter" : ["standard", "lowercase", "stop", "porter_stem"] } } } }, "mappings" : { "person" : { "dynamic" : true, "properties" : { "intro" : { "type" : "string", "indexAnalyzer" : "ik", "searchAnalyzer":"ik" } } } } } 复制代码


    查看新建的索引:

    GET /db_news/_mapping

    结果如下:



    { "db_news": { "mappings": { "person": { "dynamic": "true", "properties": { "age": { "type": "long" }, "intro": { "type": "string", "analyzer": "ik" }, "name": { "type": "string" } } } } } }


    更新字段映射

    说明:对于db_news/news,开始没有字段msgs,后来添加了这个字段,那么要先修改索引方式,在新增数据



    PUT /db_news/_mapping/news { "properties" : { "msgs" : { "type" : "string", "indexAnalyzer" : "ik", "searchAnalyzer":"ik" } } }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值