ElasticSearch查询文档基本操作实例

 更新时间:2023年02月02日 16:11:29   作者:程序员皮卡秋  
这篇文章主要为大家介绍了ElasticSearch查询文档基本操作实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

查询文档 & 基本操作

为了方便学习, 本节中所有示例沿用上节的索引

按照ID单个

GET class_1/_doc/1

查询结果:

{
  "_index" : "class_1",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 4,
  "_seq_no" : 4,
  "_primary_term" : 3,
  "found" : true,
  "_source" : {
    "name" : "l",
    "num" : 6
  }
}

按照ID批量

GET class_1/_mget
{
"ids":[1,2,3]
}

返回:

{
  "docs" : [
    {
      "_index" : "class_1",
      "_type" : "_doc",
      "_id" : "1",
      "_version" : 4,
      "_seq_no" : 4,
      "_primary_term" : 3,
      "found" : true,
      "_source" : {
        "name" : "l",
        "num" : 6
      }
    },
    {
      "_index" : "class_1",
      "_type" : "_doc",
      "_id" : "2",
      "found" : false
    },
    {
      "_index" : "class_1",
      "_type" : "_doc",
      "_id" : "3",
      "_version" : 3,
      "_seq_no" : 10,
      "_primary_term" : 4,
      "found" : true,
      "_source" : {
        "num" : 9,
        "name" : "e",
        "age" : 9,
        "desc" : [
          "hhhh"
        ]
      }
    }
  ]
}

查询文档是否存在 & 通过id判断

HEAD class_1/_doc/1

返回:

200 - OK

HEAD class_1/_doc/1000

返回:

404 - Not Found

查询部分字段内容

GET class_1/_doc/1?_source_includes=name

返回:

{
  "_index" : "class_1",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 4,
  "_seq_no" : 4,
  "_primary_term" : 3,
  "found" : true,
  "_source" : {
    "name" : "l"
  }
}

可以看到只返回了name字段, 以上是一个基本的操作,下面给大家讲下条件查询~

查询文档 & 条件查询

查询的复杂度取决于它附加的条件约束,跟我们写sql一样。下面就带大家一步一步看一下ES中如何进行条件查询~

不附加任何条件

GET class_1/_search

返回:

{
  "took" : 15,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 8,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "h2Fg-4UBECmbBdQA6VLg",
        "_score" : 1.0,
        "_source" : {
          "name" : "b",
          "num" : 6
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "iGFt-4UBECmbBdQAnVJe",
        "_score" : 1.0,
        "_source" : {
          "name" : "g",
          "age" : 8
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "iWFt-4UBECmbBdQAnVJg",
        "_score" : 1.0,
        "_source" : {
          "name" : "h",
          "age" : 9
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "imFt-4UBECmbBdQAnVJg",
        "_score" : 1.0,
        "_source" : {
          "name" : "i",
          "age" : 10
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "num" : 9,
          "name" : "e",
          "age" : 9,
          "desc" : [
            "hhhh"
          ]
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
          "name" : "f",
          "age" : 10,
          "num" : 10
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "RWlfBIUBDuA8yW5cu9wu",
        "_score" : 1.0,
        "_source" : {
          "name" : "一年级",
          "num" : 20
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "l",
          "num" : 6
        }
      }
    ]
  }
}

可以看到索引class_1中的所有数据都是上节添加的。这里提一下,我们也可以添加多个索引一起查,然后返回,用,逗号隔开就可以了

GET class_1,class_2,class_3/_search
{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 9,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "h2Fg-4UBECmbBdQA6VLg",
        "_score" : 1.0,
        "_source" : {
          "name" : "b",
          "num" : 6
        }
      },
      {
        "_index" : "class_2",
        "_type" : "_doc",
        "_id" : "RWlfBIUBDuA8yW5cu9wu",
        "_score" : 1.0,
        "_source" : {
          "name" : "一年级",
          "num" : 20
        }
      },
      ....
    ]
  }
}

可以看到返回了索引class_2中的数据,并且合并到了一起。

相关字段解释

有的小伙伴可能对返回的字段有点陌生,这里给大家统一解释一下:

{
    "took":"查询操作耗时,单位毫秒",
    "timed_out":"是否超时",
    "_shards":{
        "total":"分片总数",
        "successful":"执行成功分片数",
        "skipped":"执行忽略分片数",
        "failed":"执行失败分片数"
    },
    "hits":{
        "total":{
            "value":"条件查询命中数",
            "relation":"计数规则(eq计数准确/gte计数不准确)"
        },
        "max_score":"最大匹配度分值",
        "hits":[
            {
                "_index":"命中结果索引",
                "_id":"命中结果ID",
                "_score":"命中结果分数",
                "_source":"命中结果原文档信息"
            }
        ]
    }
}

下面我们看下带条件的查询~

基础分页查询

基本语法: es中通过参数sizefrom来进行基础分页的控制

  • from:指定跳过多少条数据
  • size:指定返回多少条数据

下面看下示例:

url参数

GET class_1/_search?from=2&size=2

返回:

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 8,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "iWFt-4UBECmbBdQAnVJg",
        "_score" : 1.0,
        "_source" : {
          "name" : "h",
          "age" : 9
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "imFt-4UBECmbBdQAnVJg",
        "_score" : 1.0,
        "_source" : {
          "name" : "i",
          "age" : 10
        }
      }
    ]
  }
}

body 参数

GET class_1/_search
{
    "from" : 2,
    "size" : 2
}

返回结果和上面是一样的~

单字段全文索引查询

这个大家应该不陌生,前面几节都见过。使用query.match进行查询,match适用与对单个字段基于全文索引进行数据检索。对于全文字段,match使用特定的分词进行全文检索。而对于那些精确值,match同样可以进行精确匹配,match查询短语时,会对短语进行分词,再针对每个词条进行全文检索。

GET class_1/_search
{
  "query": {
    "match": {
      "name":"i"
    }
  }
}

返回:

{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.3862942,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "imFt-4UBECmbBdQAnVJg",
        "_score" : 1.3862942,
        "_source" : {
          "name" : "i",
          "age" : 10
        }
      }
    ]
  }
}

单字段不分词查询

使用query.match_phrase进行查询, 它与match的区别就是不进行分词,干说,可能有点抽象,下面我们通过一个例子给大家分清楚:

先造点数据进去:

PUT class_1/_bulk
{ "create":{  } }
{"name":"I eat apple so haochi1~","num": 1}
{ "create":{  } }
{ "name":"I eat apple so zhen haochi2~","num": 1}
{ "create":{  } }
{"name":"I eat apple so haochi3~","num": 1}

假设有这么几个句子,现在我有一个需求我要把I eat apple so zhen haochi2~这句话匹配出来

match分词结果

GET class_1/_search
{
  "query": {
    "match": {
      "name": "apple so zhen"
    }
  }
}

返回:

{
  "took" : 15,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 2.2169428,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "cMfcCoYB090miyjed7YE",
        "_score" : 2.2169428,
        "_source" : {
          "name" : "I eat apple so zhen haochi2~",
          "num" : 1
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "b8fcCoYB090miyjed7YE",
        "_score" : 1.505254,
        "_source" : {
          "name" : "I eat apple so haochi1~",
          "num" : 1
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "ccfcCoYB090miyjed7YE",
        "_score" : 1.505254,
        "_source" : {
          "name" : "I eat apple so haochi3~",
          "num" : 1
        }
      }
    ]
  }
}

从结果来看,刚刚的几句话都被查出来了,但是结果并大符合预期。从score来看,"_score" : 2.2169428得分最高,排在了第一,语句是I eat apple so zhen haochi2~,说明匹配度最高,这个句子正是我们想要的结果~

match_phrase 不分词查询结果

GET class_1/_search
{
  "query": {
    "match_phrase": {
      "name": "apple so zhen"
    }
  }
}

结果:

{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 2.2169428,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "cMfcCoYB090miyjed7YE",
        "_score" : 2.2169428,
        "_source" : {
          "name" : "I eat apple so zhen haochi2~",
          "num" : 1
        }
      }
    ]
  }
}

结果符合预期,只返回了我们想要的那句。那么match为什么都返回了,这就是前面讲到的分词,首先会对name: apple so zhen进行分词,也就是说存在apple的都会被返回。

当然,真正业务中的需求比这个复杂多了,这里只是为了给大家做区分~ 下面接着看~

多字段全文索引查询

相当于对多个字段执行了match查询, 这里需要注意的是query的类型要和字段类型一致,不然会报类型异常

GET class_1/_search
{
  "query": {
    "multi_match": {
      "query": "apple",
      "fields": ["name","desc"]
    }
  }
}
{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 0.752627,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "b8fcCoYB090miyjed7YE",
        "_score" : 0.752627,
        "_source" : {
          "name" : "I eat apple so haochi1~",
          "num" : 1
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "ccfcCoYB090miyjed7YE",
        "_score" : 0.752627,
        "_source" : {
          "name" : "I eat apple so haochi3~",
          "num" : 1
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "cMfcCoYB090miyjed7YE",
        "_score" : 0.7389809,
        "_source" : {
          "name" : "I eat apple so zhen haochi2~",
          "num" : 1
        }
      }
    ]
  }
}

范围查询

使用range来进行范围查询,适用于数组时间等字段

GET class_1/_search
{
  "query": {
    "range": {
      "num": {
        "gt": 5,
        "lt": 10
      }
    }
  }
}

返回:

{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "h2Fg-4UBECmbBdQA6VLg",
        "_score" : 1.0,
        "_source" : {
          "name" : "b",
          "num" : 6
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "num" : 9,
          "name" : "e",
          "age" : 9,
          "desc" : [
            "hhhh"
          ]
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "l",
          "num" : 6
        }
      }
    ]
  }
}

单字段精确查询

使用term进行非分词字段的精确查询。需要注意的是,对于那些分词的字段,即使查询的value是一个完全匹配的短语,也无法完成查询

GET class_1/_search
{
 "query": {
   "term": {
     "num": {
       "value": "9"
     }
   }
 }
}

返回:

{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "num" : 9,
          "name" : "e",
          "age" : 9,
          "desc" : [
            "hhhh"
          ]
        }
      }
    ]
  }
}

字段精确查询 & 多值

与term一样, 区别在于可以匹配一个字段的多个值,满足一个即检索成功

GET class_1/_search
{
 "query": {
   "terms": {
     "num": [
      9,
      1
     ]
   }
 }
}

返回:

{
  "took" : 8,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "num" : 9,
          "name" : "e",
          "age" : 9,
          "desc" : [
            "hhhh"
          ]
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "b8fcCoYB090miyjed7YE",
        "_score" : 1.0,
        "_source" : {
          "name" : "I eat apple so haochi1~",
          "num" : 1
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "ccfcCoYB090miyjed7YE",
        "_score" : 1.0,
        "_source" : {
          "name" : "I eat apple so haochi3~",
          "num" : 1
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "cMfcCoYB090miyjed7YE",
        "_score" : 1.0,
        "_source" : {
          "name" : "I eat apple so zhen haochi2~",
          "num" : 1
        }
      }
    ]
  }
}

文档包含字段查询

为了确定当前索引有哪些文档包含了对应的字段,es中使用exists来实现

GET class_1/_search
{
  "query": {
    "exists": {
      "field": "desc"
    }
  }
}

返回:

{
  "took" : 8,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "num" : 9,
          "name" : "e",
          "age" : 9,
          "desc" : [
            "hhhh"
          ]
        }
      }
    ]
  }
}

结束语

本节主要讲了ES中的文档查询API操作,该部分内容较多, 下节继续给大家讲,就先消化这么多~API大家都不要去背,多敲几遍就记住了,关键是多用,多总结 。

以上就是ElasticSearch查询文档基本操作实例的详细内容,更多关于ElasticSearch查询文档的资料请关注脚本之家其它相关文章!

相关文章

  • Java中break、continue、return在for循环中的使用

    Java中break、continue、return在for循环中的使用

    这篇文章主要介绍了break、continue、return在for循环中的使用,本文是小编收藏整理的,非常具有参考借鉴价值,需要的朋友可以参考下
    2017-11-11
  • Java使用策略模式解决商场促销商品问题示例

    Java使用策略模式解决商场促销商品问题示例

    这篇文章主要介绍了Java使用策略模式解决商场促销商品问题,简单描述了策略模式的概念、原理,并结合实例形式分析了Java基于策略模式解决商品促销问题的相关操作技巧,需要的朋友可以参考下
    2018-05-05
  • Java的main方法使用及说明

    Java的main方法使用及说明

    这篇文章主要介绍了Java的main方法使用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Java高效提取PDF文件指定坐标的文本内容实战代码

    Java高效提取PDF文件指定坐标的文本内容实战代码

    在日常工作中,有时可能会需要从庞大的PDF文档中提取其中所包含的文本内容,下面这篇文章主要给大家介绍了关于如何利用Java高效提取PDF文件指定坐标的文本内容,需要的朋友可以参考下
    2024-01-01
  • java方法替换word文档中需要替换的部分操作步骤

    java方法替换word文档中需要替换的部分操作步骤

    这篇文章主要介绍了java方法替换word文档中需要替换的部分操作的相关资料,需要的朋友可以参考下,包括引入依赖、创建业务方法、测试以及扩展功能,需要的朋友们可以参考下
    2024-12-12
  • SpringBoot整合liquibase的实现方法

    SpringBoot整合liquibase的实现方法

    这篇文章主要介绍了SpringBoot整合liquibase的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Java实现图片模糊效果详解

    Java实现图片模糊效果详解

    图片模糊是图像处理中的一种常见效果,它通过平均周围像素的颜色来使图像变得模糊,下面我们来看看如何使用Swing库实现图片模糊效果吧
    2025-02-02
  • 详解如何解析pom文件方法示例

    详解如何解析pom文件方法示例

    这篇文章主要为大家介绍了详解如何解析pom文件方法示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • SpringBoot Tomcat启动实例代码详解

    SpringBoot Tomcat启动实例代码详解

    这篇文章主要介绍了SpringBoot Tomcat启动实例代码详解,需要的朋友可以参考下
    2017-09-09
  • java实现窗口刷新的示例代码

    java实现窗口刷新的示例代码

    本文主要介绍了java实现窗口刷新的示例代码,通过重写paintComponent()方法和调用repaint()方法,可以实现窗口的即时刷新,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02

最新评论