Заставить эластичный поиск только вернуть определенные поля - PullRequest
348 голосов
/ 07 марта 2012

Я использую эластичный поиск для индексации своих документов.

Можно ли поручить ему возвращать только определенные поля вместо всего документа json, который он сохранил?

Ответы [ 10 ]

481 голосов
/ 07 марта 2012

Да! Используйте фильтр источника . Если вы ищете с помощью JSON, это будет выглядеть примерно так:

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

В ES 2.4 и более ранних версиях вы также можете использовать опцию fields для API поиска :

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

Это устарело в ES 5+. В любом случае, исходные фильтры более мощные!

77 голосов
/ 04 декабря 2014

Мне показались полезными документы для get api - особенно два раздела, Исходная фильтрация и Поля : http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-get.html

Они заявляют о фильтрации источника:

Если вам нужно только одно или два поля из полного источника _, вы можете используйте параметры _source_include & _source_exclude для включения или отфильтруйте те части, которые вам нужны. Это может быть особенно полезно с большие документы, где частичный поиск может сэкономить на сетевых издержках

Который отлично подходил моему варианту использования. В итоге я просто отфильтровал источник (используя сокращение):

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

К вашему сведению, в документах говорится о параметре fields :

Операция get позволяет указать набор сохраненных полей, которые будут быть возвращен путем передачи параметра поля.

Кажется, он обслуживает поля, которые были специально сохранены, где он помещает каждое поле в массив. Если указанные поля не были сохранены, они будут извлекать каждое из источника _source, что может привести к «медленному» поиску. У меня также были проблемы при попытке заставить его возвращать поля типа объекта.

Итак, в итоге, у вас есть два варианта: либо фильтрация источника, либо [сохраненные] поля.

17 голосов
/ 14 апреля 2017
For the ES versions 5.X and above you can a ES query something like this

    GET /.../...
    {
      "_source": {
        "includes": [ "FIELD1", "FIELD2", "FIELD3" ... " ]
      },
      .
      .
      .
      .
    }
9 голосов
/ 29 марта 2017

В 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!

7 голосов
/ 26 февраля 2016

response_filtering

Все API REST принимают параметр filter_path, который можно использовать для уменьшения ответа, возвращаемогоasticsearch.Этот параметр принимает список фильтров, разделенных запятыми, с точечной нотацией.

https://stackoverflow.com/a/35647027/844700

6 голосов
/ 18 сентября 2017
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" }
        }
    }
6 голосов
/ 15 августа 2017

Здесь другое решение, теперь использующее совпадение выражение

Фильтрация источника
Позволяет контролировать, как поле _source возвращается при каждом попадании.

Протестировано с Elastiscsearch версии 5.5

Ключевое слово "включает" определяет поля специфики.

GET /my_indice/my_indice_type/_search
{
    "_source": {
        "includes": [ "my_especific_field"]
        },
        "query": {
        "bool": {
                "must": [
                {"match": {
                    "_id": "%my_id_here_without_percent%"
                    }
                }
            ]
        }
    }
}
3 голосов
/ 10 августа 2017

Запрос 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
            }
        }
    ]
}

}

2 голосов
/ 28 сентября 2018

Да, используя фильтр источника, вы можете сделать это, вот документ 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"
        },....
      }
    ]
  }
}
1 голос
/ 30 марта 2017

В Java вы можете использовать setFetchSource следующим образом:

client.prepareSearch(index).setTypes(type)
            .setFetchSource(new String[] { "field1", "field2" }, null)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...