Elasticsearch-如何控制存储和索引文档(_source、_all、返回源文档的某些字段)

本文讲解了Elasticsearch中如何利用_source和_all字段控制文档的存储与索引,包括存储文档原始内容、返回部分字段及索引所有信息的技巧。

Elasticsearch-如何控制存储和索引文档(_source、_all)

_source:可以在索引中存储文档。
_all:可以在单个字段上索引所有内容。

1. 存储原有内容的_source

_source字段按照原有格式来存储原有的文档。这一点可以看到匹配某个搜索的文档,而不仅仅是他们的ID。
_source字段的enabled可以设置为true或者false,来指定是否需要存储原始的文档。默认情况下是true,在很多情况下,设置为true还是非常有用的,因为_source的存在允许使用其他重要的ES特性。(由于很多功能都依赖于_source,而且从空间和性能的角度来看存储的成本相对低廉,在版本2.0中将无法再关闭_source选项。)
为了理解这个字段是如何工作的,来看下当检索某篇之前索引的文档时,ES通常返回什么:
(1) 先索引一篇文档

curl -XPUT 'localhost:9200/music/album/5?pretty' -d '{
"name":"七里香",
"date":"2004-08-03",
"songs":["七里香","搁浅"]
}'

(2) 检索

FengZhendeMacBook-Pro:cv FengZhen$ curl 'localhost:9200/music/album/5?pretty'

{

  "_index" : "music",

  "_type" : "album",

  "_id" : "5",

  "_version" : 1,

  "found" : true,

  "_source" : {

    "name" : "七里香",

    "date" : "2004-08-03",

    "songs" : [ "七里香", "搁浅" ]

  }

}

搜索的同时,会获得_source的JSON,因为这是默认设置会返回的内容。

2. 仅仅返回源文档的某些字段

当检索或者搜索某篇文档的时候,可以要求ES只返回特定的字段,而不是整个_source.一种实现的方法是在fields参数中提供用逗号分隔的字段列表。如下

FengZhendeMacBook-Pro:cv FengZhen$ curl -XGET 'localhost:9200/music/album/5?pretty&fields=name'

{

  "_index" : "music",

  "_type" : "album",

  "_id" : "5",

  "_version" : 1,

  "found" : true,

  "fields" : {

    "name" : [ "七里香" ]

  }

}

如果_source已经被存储,ES从那里获取所需的字段。也可以通过设置store选项为yes来存储个别的字段。举个例子,如果只需要存储test_name字段,映射如下

curl -XPUT 'localhost:9200/music/_mapping/test' -d '{
    "test":{
        "properties":{
            "test_name":{
                "type":"string",
                "store":"yes"
            }
        }
    }
}'

向ES请求特定的字段时,这样做可能会很有帮助,原因是相对于检索整个_source然后再抽取而言,检索单一的存储字段要更快一些,尤其是在文档很大的时候。
注意:当存储单独的字段时,应该考虑到存储的越多,索引越大。更大的索引经常意味着更慢的索引和搜索速度。
就其内部来看,_source只是另一个Lucene中的存储字段。ES将原始的JSON存储于其中,然后按需抽取字段。

3. 索引一切的_all

_all是索引所有的信息。当搜索_all字段的时候,ES将在不考虑是哪个字段匹配成功的情况下,返回命中的文档。当用户不知道在哪里查询某些内容的时候,这一点非常有用。
从URI上运行搜索时如果不指定字段名称,系统默认情况下将会在_all上搜索:

curl 'localhost:9200/music/album/_search?pretty' -d '{
    "query":{
        "query_string":{
            "query":"八度空间"
        }
    }
}'

如果总是在特定的字段上搜索,可以通过设置enabled为false来关闭_all:

"events":{
"_all":{"enabled":false}
}

如此设置会使得索引的规模变得更小,而且索引操作变得更快。
默认情况下,include_in_all隐式的设置为true,每个字段都会包含在_all之中。可以使用这个选项来控制哪些字段被_all包含,而哪些不被_all包含。
(1).将test_date字段设置为不在_all中

curl -XPUT 'localhost:9200/music/_mapping/test' -d '{
    "test":{
        "properties":{
            "test_date":{
                "type":"date",
                "include_in_all":false
            }
        }
    }
}'

(2).索引新文档

curl -XPUT 'localhost:9200/music/test/1?pretty' -d '{
    "test_name":"八度空间",
    "test_date":"2002-07-18",
    "test_songs":["半兽人","回到过去","米兰的小铁匠","最后的战役"]
}'

(3).查询

FengZhendeMacBook-Pro:cv FengZhen$ curl 'localhost:9200/music/test/_search?q=2002-07-18&pretty'
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : null,
    "hits" : [ ]
  }
}

此时,不指定字段查询,已经查不出数据了
使用include_in_all的选项,将赋予更高的灵活性,灵活性不仅体现在空间存储上,同样体现在查询的表现方式上。如果一次搜索在没有指定字段的情形下运行,ES只会匹配_all所包含的字段。

转载于:https://www.cnblogs.com/EnzoDin/p/11111522.html

<think>我们参考用户提供的站内引用,特别是引用[1][2],因为问题涉及使用RestHighLevelClient获取指定字段的值。用户问题:如何使用restHighLevelClient在Elasticsearch中获取指定索引文档ID下的某个字段的值步骤:1.构建RestHighLevelClient客户端(如引用[1]所示)2.使用GetRequest指定索引文档ID(引用[1]提到过文档操作,但具体获取字段需要查看相关API)3.设置需要获取的字段(通过`fetchSourceContext`指定包含的字段)4.执行请求并解析结果引用[2]中提到_source可以设置包含或排除字段,这在请求中指定字段类似。由于引用[1]的代码中已经包含了建立连接关闭连接的示例,我们可以在此基础上构建。具体代码步骤:a.创建GetRequest对象,设置索引名称文档id。b.使用`fetchSourceContext`来指定返回字段(例如,只返回一个字段"title")。c.客户端执行get请求,得到GetResponse。d.从GetResponse中获取_source,然后从中提取指定字段。注意:RestHighLevelClient在7.15.0版本后已弃用,但根据引用[3][5],用户使用的是7.4.2,所以可以用。另外,如果文档存储了该字段(即_source中包含了该字段),那么就可以获取到。代码示例:假设我们要从索引"my_index"中获取id为"1"的文档的"title"字段。参考引用[1]的测试类结构,我们在测试方法中编写。</think> ### 如何用RestHighLevelClient获取ES文档特定字段值 在Java中使用RestHighLevelClient获取Elasticsearch指定文档的特定字段值,主要步骤如下: ```java // 1. 构建GetRequest并指定索引文档ID GetRequest request = new GetRequest("your_index_name", "your_document_id"); // 2. 设置需要返回字段(此处以"title"字段为例) String[] includes = {"title"}; // 需要包含的字段 String[] excludes = {}; // 需要排除的字段 request.fetchSourceContext(new FetchSourceContext(true, includes, excludes)); // 3. 执行请求并处理响应 GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT); // 4. 提取指定字段的值 if (response.isExists()) { Map<String, Object> sourceAsMap = response.getSourceAsMap(); String fieldValue = (String) sourceAsMap.get("title"); System.out.println("Field value: " + fieldValue); } else { System.out.println("Document not found"); } ``` **关键点说明:** 1. **字段筛选**:通过`fetchSourceContext()`实现字段过滤[^1] - `includes`参数声明需要返回字段(支持多个字段- `excludes`参数声明需排除的字段 2. **字段类型处理**:返回值需根据字段类型转换(如text转为String,float转为Float)[^2] 3. **错误处理**:建议添加`try-catch`处理Elasticsearch异常 **配置前提:** 1. Maven依赖配置(如引用[3][5]所示): ```xml <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.17.10</version> <!-- 按实际版本调整 --> </dependency> ``` 2. 客户端初始化配置(如引用[1][5]所示): ```java RestHighLevelClient client = new RestHighLevelClient( RestClient.builder(new HttpHost("localhost", 9200, "http")) ); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值