我使用elasticsearch来索引我的文档。
是否有可能指示它只返回特定的字段,而不是它所存储的整个json文档?
是的,使用一个更好的选项源滤波器。如果你使用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
get api
他们阐述了源过滤:
如果你只需要完整_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定义了具体字段。
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" }
如果你想返回name和score,你可以使用下面的命令:
name
score
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" } } ] }
文档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" } } ] } }