【发布时间】:2012-03-25 04:56:37
【问题描述】:
我正在使用 elasticsearch 来索引我的文档。
是否可以指示它只返回特定字段而不是它存储的整个 json 文档?
【问题讨论】:
-
elastic.co/guide/en/elasticsearch/reference/current/…,注意你也可以只排除一些字段
标签: elasticsearch
我正在使用 elasticsearch 来索引我的文档。
是否可以指示它只返回特定字段而不是它存储的整个 json 文档?
【问题讨论】:
标签: elasticsearch
有几种方法可用于实现特定领域的结果。 一种可以通过source方法。 filter_path:filter_path:
文档 Json:
"hits" : [
{
"_index" : "xxxxxx",
"_type" : "_doc",
"_id" : "xxxxxx",
"_score" : xxxxxx,
"_source" : {
"year" : 2020,
"created_at" : "2020-01-29",
"url" : "www.github.com/mbarr0987",
"name":"github"
}
}
查询:
GET bot1/_search?filter_path=hits.hits._source.url
{
"query": {
"bool": {
"must": [
{"term": {"name.keyword":"github" }}
]
}
}
}
输出:
{
"hits" : {
"hits" : [
{
"_source" : {
"url" : "www.github.com/mbarr0987"
}
}
]
}
}
【讨论】:
所有 REST API 都接受一个 filter_path 参数,该参数可用于 减少elasticsearch返回的响应。该参数采用 用点表示法表示的过滤器的逗号分隔列表。
【讨论】:
这是另一个解决方案,现在使用 match 表达式
Source filtering 允许控制每次点击时如何返回 _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%"
}
}
]
}
}
}
【讨论】:
here you can specify whichever field you want in your output and also which you don't.
POST index_name/_search
{
"_source": {
"includes": [ "field_name", "field_name" ],
"excludes": [ "field_name" ]
},
"query" : {
"match" : { "field_name" : "value" }
}
}
【讨论】:
对于 ES 版本 5.X 及更高版本,您可以进行 ES 查询,如下所示:
GET /.../...
{
"_source": {
"includes": [ "FIELD1", "FIELD2", "FIELD3" ... " ]
},
.
.
.
.
}
【讨论】:
是的,使用更好的选项source filter。如果您使用 JSON 进行搜索,它将看起来像这样:
{
"_source": ["user", "message", ...],
"query": ...,
"size": ...
}
在 ES 2.4 及更早版本中,您还可以使用fields option to the search API:
{
"fields": ["user", "message", ...],
"query": ...,
"size": ...
}
这在 ES 5+ 中已弃用。而且源过滤器更强大!
【讨论】:
如果你知道sql,请写一个查询来获取代码的值,例如sql查询等效和elasticsearch查询
POST /_sql/translate
{
"query": "select name,surname from users"
}
结果是,仔细看包含键
{
"size" : 1000,
"_source" : {
"includes" : [
"name",
"surname"
],
"excludes" : [ ]
},
"sort" : [
{
"_doc" : {
"order" : "asc"
}
}
]
}
【讨论】:
例如,您有一个包含三个字段的文档:
PUT movie/_doc/1
{
"name":"The Lion King",
"language":"English",
"score":"9.3"
}
如果要返回name和score可以使用以下命令:
GET movie/_doc/1?_source_includes=name,score
如果你想得到一些匹配模式的字段:
GET movie/_doc/1?_source_includes=*re
可能会排除一些字段:
GET movie/_doc/1?_source_excludes=score
【讨论】:
我发现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": {
...
}
}
仅供参考,他们在文档中说明了 fields 参数:
get 操作允许指定一组存储字段,这些字段将 通过传递 fields 参数返回。
它似乎适合专门存储的字段,它将每个字段放在一个数组中。如果指定的字段尚未存储,它将从 _source 中获取每个字段,这可能会导致“较慢”的检索。我也很难让它返回对象类型的字段。
因此,总而言之,您有两个选择,通过源过滤或 [存储] 字段。
【讨论】:
是的,通过使用源过滤器你可以做到这一点,这里是文档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"
},....
}
]
}
}
【讨论】:
可以使用“_source”参数发出 REST API GET 请求。
示例请求
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
}
}
]
}
}
【讨论】:
在java中你可以像这样使用setFetchSource:
client.prepareSearch(index).setTypes(type)
.setFetchSource(new String[] { "field1", "field2" }, null)
【讨论】:
在 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":{
}
}
请参阅有关如何索引存储字段的文档。 总是为 Upvote 感到高兴!
【讨论】: