Elasticsearch笔记-深入查询

转载自: http://blog.csdn.net/wthfeng/article/details/52953317


上一篇笔记Elasticsearch笔记-索引与查询我们介绍了ES的简单的增删查改,这一次我们深入ES较为复杂的查询,比如SQL中常用的select in 、模糊查询、返回部分字段等等。

一般来说,ES的真正用途在于分布式的搜索引擎,由于其稳定快速的查询性能又被当做数据库使用。

承接上一篇数据,此时posts索引article类型中的数据如下:

{
    "hits": {
        "total": 4,
        "max_score": 1,
        "hits": [{
            "_index": "posts",
            "_type": "article",
            "_id": "5",
            "_score": 1,
            "_source": {
                "id": 5,
                "name": "生活日志",
                "author": "wthfeng",
                "date": "2015-09-21",
                "contents": "这是日常生活的记录"
            }
        }, {
            "_index": "posts",
            "_type": "article",
            "_id": "4",
            "_score": 1,
            "_source": {
                "id": 4,
                "name": "javascript指南",
                "author": "wthfeng",
                "date": "2016-09-21",
                "contents": "js的权威指南"
            }
        }, {
            "_index": "posts",
            "_type": "article",
            "_id": "2",
            "_score": 1,
            "_source": {
                "id": 2,
                "name": "更新后的文档",
                "author": "wthfeng",
                "date": "2016-10-23",
                "contents": "这是我的javascript学习笔记",
                "brief": "简介,这是新加的字段"
            }
        }, {
            "_index": "posts",
            "_type": "article",
            "_id": "1",
            "_score": 1,
            "_source": {
                "id": 1,
                "name": "ES更新过的文档",
                "author": "wthfeng",
                "date": "2016-10-25",
                "contents": "这是更新内容"
            }
        }]
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

1. 返回指定字段(fields)

查看我们的返回结果,每一个都带有_source字段,里面包含原始的数据。我们都是从这个字段查询出所需的结果。返回_source 字段是默认的行为,如果我们只想返回某些字段,那这些字段在创建索引时必须开启store字段。

上一篇定义的article映射部分:

{
    "properties": {
        "id": {
            "type": "long",
            "store": "yes"  //开启储存
        },
        //......省略其他字段
        "contents": {
            "type": "string",
            "store": "no"  //未开启储存,默认
        }
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

现在要求返回文章名称带文档 两词的所有文章,且只返回idname字段。

curl localhost:9200/posts/article/_search?pretty -d @search.json

{
    "fields": ["id", "name"],
    "query": {
        "match": {
            "name": "文档"
        }
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

返回数据部分

  {
    "hits": {
        "total": 2,
        "max_score": 0.53033006,
        "hits": [{
            "_index": "posts",
            "_type": "article",
            "_id": "2",
            "_score": 0.53033006,
            "fields": {
                "name": ["更新后的文档"],
                "id": [2]
            }
        }, {
            "_index": "posts",
            "_type": "article",
            "_id": "1",
            "_score": 0.16273327,
            "fields": {
                "name": ["ES更新过的文档"],
                "id": [1]
            }
        }]
    }
  }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

可见结果只有指定的字段。且用fields字段代替了_source字段。类似SQL中:

select id,name from article where name like '%文档%'
 
 
  • 1
  • 如果查询中没有fields字段,那默认返回_source字段
  • 虽然返回更少字段,但返回_source字段比返回多个储存字段性能要好,所以无特殊要求,返回_source较好。

2. 多词条查询(terms)

多词条查询类似于SQL中的in 操作符。可以匹配在查询内容中含有的多个词条。注意,terms匹配的是未经分析的词条,也就是必须完全匹配。

查询16年10月23号和25号发表的文章

curl localhost:9200/posts/article/_search -d @search.json

{
    "query":{
        "terms":{
            "date":["2016-10-23","2016-10-25"]
        }
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

注意:terms查询的词是未经分析的。它相当于term的复数版本。 
类似于SQL:

select * from article where date in('2016-10-23','2016-10-25') 
 
 
  • 1

3. 范围查询(range)

范围查询(range)即返回指定范围的文档,多用于数值型和日期型中。

查询日期在10月23日及之前发表的,且文章名含有“指南”两字文章。

curl localhost:9200/posts/article/_search?pretty -d @search.json

{
    "query":{
        "range":{
            "date":{
                "lte":"2016-10-23"
            }
        }
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

结果正确返回,这里就不贴了。范围查询支持以下参数:

  • gte :大于或等于
  • gt :大于
  • lte :小于或等于
  • lt :小于

此例在SQL中很容易表示:

select * from article where date <= '2016-10-23'
 
 
  • 1

4. 排序(sort)

默认的ES按文档的相关度排序,即与指定查询吻合度最高的排在前面。如果我们想修改默认排序,需使用sort字段与query 字段并列。

查询文档内容含有”的”字所有文档并按日期、id排序

curl localhost:9200/posts/article/_search?pretty -d @search.json

{
    "query":{
        "match":{
            "contents":"的"
        }
    },
    "sort":[
        {"date":"desc"},
        {"id":"asc"}
    ]
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

sort接收一个数组,可以指定多个排序字段,用ascdesc 指定正序倒序

SQL 语句为

select * from article where contents like '%的%' order by date desc,id asc
 
 
  • 1
缺省字段的排序

默认情况下,如果某文档没有指定的排序字段或该值为null,那么,如果升序排,该文档排在最前面,倒序排排在最后面。也就是缺省值的文档序列号是最小的。 
我们可以用missing 修改这种默认行为。_first 指定排在最前列,_last 指定排在最后列。还可指定具体数值,则缺省值就当做此值。

将缺省值都放在前列

{
    "query":{
        "match":{
            "contents":"的"
        }
    },
    "sort":[
        {"date":{
            "order":"desc",
            "missing":"_first"

        }},
        {"id":{
            "order":"asc",
            "missing":"_first"
        }}
    ]
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

布尔查询(bool)

是时候将这些查询聚在一起了,布尔查询负责此工作。类似于SQL中and 和or 等的作用 
在布尔查询中

  • should : 类似于or,可以匹配条件也可以不匹配
  • must : 类似于and,必须匹配
  • must_not : 类似于!=,必须不匹配

以上关键字需包含在bool 语句中。

查询16年10月以来名称含有“ES”的文档,且id不为1

{
    "query": {
        "bool": {
            "should": {

            },
            "must": [{
                "match": {
                    "name": { "query": "ES" } }
            }, {
                "range": {
                    "date": { "gte": "2016-10-01" } }
            }],
            "must_not": {
                "term": {
                    "id": "1" }
            }
        }
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

需要注意的是查询的格式要求,should、must、must_not可以带一个或多个查询条件。注意无论怎样的查询条件都首先满足json的格式要求。

上面写成SQL类似于

select * from article where name like '%ES%' and date > '2016-10-01' and id !=1 
 
 
  • 1

———————end ———————–

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值