Sto usando elasticsearch per indicizzare i miei documenti.
È possibile indicare che restituisce solo campi particolari anziché l'intero documento json che ha memorizzato?
Sto usando elasticsearch per indicizzare i miei documenti.
È possibile indicare che restituisce solo campi particolari anziché l'intero documento json che ha memorizzato?
Risposte:
Sì! Usa un filtro sorgente . Se stai cercando con JSON sarà simile a questo:
{
"_source": ["user", "message", ...],
"query": ...,
"size": ...
}
In ES 2.4 e precedenti, è possibile utilizzare anche l' opzione campi nell'API di ricerca :
{
"fields": ["user", "message", ...],
"query": ...,
"size": ...
}
Questo è deprecato in ES 5+. E i filtri sorgente sono comunque più potenti!
Ho trovato utili i documenti per l'argomento, in get api
particolare le due sezioni, Filtro sorgente e Campi : https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-get.html#get-source- filtraggio
Dichiarano il filtro sorgente:
Se sono necessari solo uno o due campi dell'intera _source completa, è possibile utilizzare i parametri _source_include e _source_exclude per includere o filtrare le parti necessarie. Ciò può essere particolarmente utile con documenti di grandi dimensioni in cui il recupero parziale può risparmiare sull'overhead di rete
Che si adattava perfettamente alla mia custodia. Ho finito semplicemente filtrando la fonte in questo modo (usando la scorciatoia):
{
"_source": ["field_x", ..., "field_y"],
"query": {
...
}
}
Cordiali saluti, dichiarano nei documenti sul parametro field :
L'operazione get consente di specificare un set di campi memorizzati che verranno restituiti passando il parametro fields.
Sembra soddisfare i campi che sono stati specificamente memorizzati, dove colloca ciascun campo in un array. Se i campi specificati non sono stati memorizzati, verranno recuperati tutti da _source, il che potrebbe comportare il recupero più lento. Ho anche avuto problemi a provare a ottenerlo per restituire campi di tipo oggetto.
Quindi, in sintesi, hai due opzioni, attraverso il filtro di origine o i campi [memorizzati].
For the ES versions 5.X and above you can a ES query something like this
GET /.../...
{
"_source": {
"includes": [ "FIELD1", "FIELD2", "FIELD3" ... " ]
},
.
.
.
.
}
In Elasticsearch 5.x l'approccio sopra menzionato è obsoleto. È possibile utilizzare l'approccio _source, ma in determinate situazioni può avere senso memorizzare un campo. Ad esempio, se hai un documento con un titolo, una data e un campo di contenuto molto grande, potresti voler recuperare solo il titolo e la data senza dover estrarre quei campi da un grande campo _source:
In questo caso, useresti:
{
"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":{
}
}
Consulta la documentazione su come indicizzare i campi memorizzati. Sempre felice per un voto!
Tutte le API REST accettano un parametro filter_path che può essere utilizzato per ridurre la risposta restituita da elasticsearch. Questo parametro accetta un elenco separato da virgole di filtri espressi con la notazione punto.
Ecco un'altra soluzione, che ora utilizza un'espressione di corrispondenza
Filtro sorgente
Consente di controllare come viene restituito il campo _source ad ogni hit.
Testato con Elastiscsearch versione 5.5
La parola chiave "include" definisce i campi specifici.
GET /my_indice/my_indice_type/_search
{
"_source": {
"includes": [ "my_especific_field"]
},
"query": {
"bool": {
"must": [
{"match": {
"_id": "%my_id_here_without_percent%"
}
}
]
}
}
}
È possibile effettuare una richiesta GET API REST con il parametro '_source'.
Richiesta di esempio
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
Risposta
{
"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
}
}
]
}
}
Sì, usando il filtro sorgente puoi farlo, ecco il filtro sorgente del documento
Richiesta di esempio
POST index_name/_search
{
"_source":["field1","filed2".....]
}
L'output sarà
{
"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"
},....
}
]
}
}
In Java puoi usare setFetchSource in questo modo:
client.prepareSearch(index).setTypes(type)
.setFetchSource(new String[] { "field1", "field2" }, null)
Ad esempio, hai un documento con tre campi:
PUT movie/_doc/1
{
"name":"The Lion King",
"language":"English",
"score":"9.3"
}
Se vuoi tornare name
e score
puoi usare il seguente comando:
GET movie/_doc/1?_source_includes=name,score
Se vuoi ottenere alcuni campi che corrispondono a un modello:
GET movie/_doc/1?_source_includes=*re
Forse escludere alcuni campi:
GET movie/_doc/1?_source_excludes=score
Utilizzando l'API Java, utilizzo quanto segue per ottenere tutti i record da un insieme di campi particolari:
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;
}