Fai che elasticsearch restituisca solo determinati campi?


Risposte:


620

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!


12
assicurati di definirli come "memorizzati": vero nella mappatura. Altrimenti ES caricherà comunque il documento _source e caricherà i campi da lì. Può influire sulle prestazioni se i dati restituiti sono relativamente piccoli rispetto alle dimensioni di un intero documento.
Zaar Hai,

6
intendevi "store": true
sscarduzio,

sono fatti nel file conf o dove esattamente?
vbNewbie,

@vbNewbie: ovunque tu stia definendo il mapping. Se non si sta definendo la mappatura in modo esplicito e non si fa affidamento su ES per generarla, è necessario definire la mappatura per i campi che si desidera vengano archiviati da ES. È possibile definire la mappatura solo per i campi in cui si desidera un comportamento speciale (ad es. "Store": true, "index": "not_analyzed") o tutti i campi. Consulta i documenti di mappatura per maggiori dettagli.
Sangharsh

3
campi non è più supportato nelle versioni più recenti. usa invece stored_fields :)
Sachin Sharma,

88

Ho trovato utili i documenti per l'argomento, in get apiparticolare 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].


Ha fatto il trucco per me. Ho avuto un problema con la restituzione di geo_point usando "fields", ma "_source" funziona bene, grazie!
Yonnaled,

23
For the ES versions 5.X and above you can a ES query something like this

    GET /.../...
    {
      "_source": {
        "includes": [ "FIELD1", "FIELD2", "FIELD3" ... " ]
      },
      .
      .
      .
      .
    }

12

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!


7
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" }
        }
    }



5

È 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
            }
        }
    ]
}

}


Questo è molto utile per me.
Thusitha Indunil,

4

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"
        },....
      }
    ]
  }
}

2

In Java puoi usare setFetchSource in questo modo:

client.prepareSearch(index).setTypes(type)
            .setFetchSource(new String[] { "field1", "field2" }, null)

2

Ad esempio, hai un documento con tre campi:

PUT movie/_doc/1
{
  "name":"The Lion King",
  "language":"English",
  "score":"9.3"
}

Se vuoi tornare namee scorepuoi 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

0

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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.