Я використовую еластичний пошук, щоб індексувати свої документи.
Чи можна доручити йому повертати лише окремі поля замість всього документа json, який він зберігав?
Я використовую еластичний пошук, щоб індексувати свої документи.
Чи можна доручити йому повертати лише окремі поля замість всього документа 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- фільтрація
Вони заявляють про фільтрацію джерел:
Якщо вам потрібно лише одне або два поля з повного _source, ви можете використовувати параметри _source_include & _source_exclude, щоб включити або відфільтрувати потрібні вам частини. Це може бути особливо корисно для великих документів, де часткове завантаження може економити накладні витрати в мережі
Що ідеально підходило моєму використанню. Я в кінцевому підсумку просто фільтрував джерело так (за допомогою скорочення):
{
"_source": ["field_x", ..., "field_y"],
"query": {
...
}
}
FYI, вони в документах констатують параметр полів :
Операція get дозволяє вказати набір збережених полів, які будуть повернуті, передавши параметр поля.
Здається, задовольняє спеціально збережені поля, де вони розміщують кожне поле у масиві. Якщо вказані поля не будуть збережені, вони отримують кожне з _source, що може призвести до "повільніших" пошуків. У мене також виникли проблеми, намагаючись змусити його повернути поля типу об'єкта.
Отже, підсумовуючи, у вас є два варіанти: фільтрування джерел або [збережені] поля.
For the ES versions 5.X and above you can a ES query something like this
GET /.../...
{
"_source": {
"includes": [ "FIELD1", "FIELD2", "FIELD3" ... " ]
},
.
.
.
.
}
У програмі Elasticsearch 5.x вищезазначений підхід застарів. Можна використовувати підхід _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":{
}
}
Дивіться документацію про те, як індексувати збережені поля. Завжди раді за оновлення!
Усі API REST приймають параметр filter_path, який може бути використаний для зменшення відповіді, поверненої elastralsearch. Цей параметр містить список відокремлених комами фільтрів, виражених нотацією крапок.
Ось ще одне рішення, тепер використовується вираз відповідності
Фільтрація джерела
Дозволяє контролювати те, як повертається поле _source при кожному зверненні.
Протестовано у версії 5.5 Elastiscsearch
Ключове слово "включає" визначає поля специфіки.
GET /my_indice/my_indice_type/_search
{
"_source": {
"includes": [ "my_especific_field"]
},
"query": {
"bool": {
"must": [
{"match": {
"_id": "%my_id_here_without_percent%"
}
}
]
}
}
}
Запит RET 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
}
}
]
}
}
Так, використовуючи джерельний фільтр, ви можете досягти цього, ось фільтрування джерела документа
Приклад запиту
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"
},....
}
]
}
}
У Java ви можете використовувати setFetchSource так:
client.prepareSearch(index).setTypes(type)
.setFetchSource(new String[] { "field1", "field2" }, null)
Наприклад, у вас є документ з трьома полями:
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
Використовуючи Java API, я використовую наступне, щоб отримати всі записи з набору певних полів:
public List<Map<String, Object>> getAllDocs(String indexName) throws IOException{
int scrollSize = 1000;
List<Map<String,Object>> data = new ArrayList<>();
SearchResponse response = null;
while( response == null || response.getHits().getHits().length != 0){
response = client.prepareSearch(indexName)
.setTypes("typeName") // The document types to execute the search against. Defaults to be executed against all types.
.setQuery(QueryBuilders.matchAllQuery())
.setFetchSource(new String[]{"field1", "field2"}, null)
.setSize(scrollSize)
.execute()
.actionGet();
for(SearchHit hit : response.getHits()){
System.out.println(hit.getSourceAsString());
}
}
return data;
}