使elasticsearch只返回某些字段?

我使用elasticsearch来索引我的文档。

是否有可能指示它只返回特定的字段,而不是它所存储的整个json文档?

418302 次浏览

是的,使用一个更好的选项源滤波器。如果你使用JSON进行搜索,它会是这样的:

{
"_source": ["user", "message", ...],
"query": ...,
"size": ...
}

在ES 2.4和更早的版本中,你也可以使用字段选项到搜索API:

{
"fields": ["user", "message", ...],
"query": ...,
"size": ...
}

这在ES 5+中已弃用。而且源过滤器更强大!

我发现get api的文档很有帮助——尤其是两个部分,源过滤字段: https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-get.html#get-source-filtering

他们阐述了源过滤:

如果你只需要完整_source中的一个或两个字段,你可以 使用_source_include &_source_exclude参数包含或 过滤掉你需要的部分。这一点特别有用 大型文档,其中部分检索可以节省网络开销

这非常适合我的用例。我最终只是像这样简单地过滤源代码(使用简写):

{
"_source": ["field_x", ..., "field_y"],
"query": {
...
}
}

供参考,他们在文档中声明了字段参数:

get操作允许指定一组存储字段 通过传递fields参数返回

它似乎是为了满足特定存储的字段,它将每个字段放在一个数组中。如果指定的字段还没有被存储,它将从_source中获取每个字段,这可能会导致“更慢”的检索。我也有麻烦试图让它返回类型对象的字段。

因此,总的来说,您有两个选择,要么通过源过滤,要么通过[存储]字段。

response_filtering

所有REST api都接受一个filter_path参数 减少elasticsearch返回的响应。此参数取 逗号分隔的过滤器列表,用点符号表示

https://stackoverflow.com/a/35647027/844700 < a href = " https://stackoverflow.com/a/35647027/844700 " > < / >

在Elasticsearch 5。X上述方法是不赞成的。 你可以使用_source方法,但是在某些情况下,存储一个字段是有意义的。例如,如果您有一个带有标题、日期和一个非常大的内容字段的文档,您可能希望只检索标题和日期,而不必从一个大的_source字段中提取这些字段:

在这种情况下,你可以使用:

{
"size": $INT_NUM_OF_DOCS_TO_RETURN,
"stored_fields":[
"doc.headline",
"doc.text",
"doc.timestamp_utc"
],
"query":{
"bool":{
"must":{
"term":{
"doc.topic":"news_on_things"
}
},
"filter":{
"range":{
"doc.timestamp_utc":{
"gte":1451606400000,
"lt":1483228800000,
"format":"epoch_millis"
}
}
}
}
},
"aggs":{


}
}

请参阅如何为存储字段建立索引的文档。 总是很高兴得到好评!< / p >

在java中,你可以这样使用setFetchSource:

client.prepareSearch(index).setTypes(type)
.setFetchSource(new String[] { "field1", "field2" }, null)

对于ES版本5。X及以上,你可以这样查询ES:

    GET /.../...
{
"_source": {
"includes": [ "FIELD1", "FIELD2", "FIELD3" ... " ]
},
.
.
.
.
}

REST API GET请求可以使用'_source'参数进行。

示例请求

http://localhost:9200/opt_pr/_search?q=SYMBOL:ITC AND OPTION_TYPE=CE AND TRADE_DATE=2017-02-10 AND EXPIRY_DATE=2017-02-23&_source=STRIKE_PRICE

响应

{
"took": 59,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 104,
"max_score": 7.3908954,
"hits": [
{
"_index": "opt_pr",
"_type": "opt_pr_r",
"_id": "AV3K4QTgNHl15Mv30uLc",
"_score": 7.3908954,
"_source": {
"STRIKE_PRICE": 160
}
},
{
"_index": "opt_pr",
"_type": "opt_pr_r",
"_id": "AV3K4QTgNHl15Mv30uLh",
"_score": 7.3908954,
"_source": {
"STRIKE_PRICE": 185
}
},
{
"_index": "opt_pr",
"_type": "opt_pr_r",
"_id": "AV3K4QTgNHl15Mv30uLi",
"_score": 7.3908954,
"_source": {
"STRIKE_PRICE": 190
}
},
{
"_index": "opt_pr",
"_type": "opt_pr_r",
"_id": "AV3K4QTgNHl15Mv30uLm",
"_score": 7.3908954,
"_source": {
"STRIKE_PRICE": 210
}
},
{
"_index": "opt_pr",
"_type": "opt_pr_r",
"_id": "AV3K4QTgNHl15Mv30uLp",
"_score": 7.3908954,
"_source": {
"STRIKE_PRICE": 225
}
},
{
"_index": "opt_pr",
"_type": "opt_pr_r",
"_id": "AV3K4QTgNHl15Mv30uLr",
"_score": 7.3908954,
"_source": {
"STRIKE_PRICE": 235
}
},
{
"_index": "opt_pr",
"_type": "opt_pr_r",
"_id": "AV3K4QTgNHl15Mv30uLw",
"_score": 7.3908954,
"_source": {
"STRIKE_PRICE": 260
}
},
{
"_index": "opt_pr",
"_type": "opt_pr_r",
"_id": "AV3K4QTgNHl15Mv30uL5",
"_score": 7.3908954,
"_source": {
"STRIKE_PRICE": 305
}
},
{
"_index": "opt_pr",
"_type": "opt_pr_r",
"_id": "AV3K4QTgNHl15Mv30uLd",
"_score": 7.381078,
"_source": {
"STRIKE_PRICE": 165
}
},
{
"_index": "opt_pr",
"_type": "opt_pr_r",
"_id": "AV3K4QTgNHl15Mv30uLy",
"_score": 7.381078,
"_source": {
"STRIKE_PRICE": 270
}
}
]
}

下面是另一个解决方案,现在使用匹配表达式

源过滤允许控制每次命中_source字段的返回方式。

使用Elastiscsearch 5.5版进行测试

关键字includes定义了具体字段。

GET /my_indice/my_indice_type/_search
{
"_source": {
"includes": [
"my_especific_field"
]
},
"query": {
"bool": {
"must": [
{
"match": {
"_id": "%my_id_here_without_percent%"
}
}
]
}
}
}

在这里,你可以在输出中指定你想要的字段,也可以指定你不想要的字段:

  POST index_name/_search
{
"_source": {
"includes": [ "field_name", "field_name" ],
"excludes": [ "field_name" ]
},
"query" : {
"match" : { "field_name" : "value" }
}
}

是的,通过使用源过滤器你可以做到这一点,这里是doc source-filtering

示例请求

POST index_name/_search
{
"_source":["field1","filed2".....]
}

输出将是

{
"took": 57,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "index_name",
"_type": "index1",
"_id": "1",
"_score": 1,
"_source": {
"field1": "a",
"field2": "b"
},
{
"field1": "c",
"field2": "d"
},....
}
]
}
}

例如,你有一个有三个字段的doc:

PUT movie/_doc/1
{
"name":"The Lion King",
"language":"English",
"score":"9.3"
}

如果你想返回namescore,你可以使用下面的命令:

GET movie/_doc/1?_source_includes=name,score

如果你想获得一些匹配模式的字段:

GET movie/_doc/1?_source_includes=*re

可能会排除一些字段:

GET movie/_doc/1?_source_excludes=score

如果你懂sql,请写一个查询来获取代码的值,例如sql查询等价和elasticsearch查询

POST /_sql/translate
{
  

"query": "select name,surname from users"
}

结果是,请仔细查看includes键

{
"size" : 1000,
"_source" : {
"includes" : [
"name",
"surname"
],
"excludes" : [ ]
},
"sort" : [
{
"_doc" : {
"order" : "asc"
}
}
]
}


有几种方法可以用于实现特定领域的结果。 可以通过方法。 另一个方法也可以根据我们的兴趣获得更清晰和更概括的答案,它是filter_path:

文档Json在索引"index1"

"hits" : [
{
"_index" : "index1",
"_type" : "_doc",
"_id" : "1",
"_score" : 1,
"_source" : {
"year" : 2020,
"created_at" : "2020-01-29",
"url" : "www.github.com/mbarr0987",
"name":"github"
}
}

查询:

GET index1/_search?filter_path=hits.hits._source.url
{
"query": {
{"term": {"name":"github" }
}
}
}

输出:

{
"hits" : {
"hits" : [
{
"_source" : {
"url" : "www.github.com/mbarr0987"
}
}
]
}
}