Ich verwende Elasticsearch, um meine Dokumente zu indizieren.
Ist es möglich, es anzuweisen, nur bestimmte Felder anstelle des gesamten gespeicherten JSON-Dokuments zurückzugeben?
Ich verwende Elasticsearch, um meine Dokumente zu indizieren.
Ist es möglich, es anzuweisen, nur bestimmte Felder anstelle des gesamten gespeicherten JSON-Dokuments zurückzugeben?
Antworten:
Ja! Verwenden Sie einen Quellfilter . Wenn Sie mit JSON suchen, sieht es ungefähr so aus:
{
"_source": ["user", "message", ...],
"query": ...,
"size": ...
}
In ES 2.4 und früheren Versionen können Sie auch die Feldoption für die Such-API verwenden :
{
"fields": ["user", "message", ...],
"query": ...,
"size": ...
}
Dies ist in ES 5+ veraltet. Und Quellfilter sind sowieso leistungsfähiger!
Ich fand die Dokumente get api
hilfreich, insbesondere die beiden Abschnitte Quellfilterung und Felder : https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-get.html#get-source- Filtern
Sie geben über die Quellfilterung an:
Wenn Sie nur ein oder zwei Felder aus der vollständigen _source benötigen, können Sie die Parameter _source_include & _source_exclude verwenden, um die benötigten Teile einzuschließen oder herauszufiltern. Dies kann besonders bei großen Dokumenten hilfreich sein, bei denen durch teilweises Abrufen Netzwerk-Overhead eingespart werden kann
Welches passte perfekt zu meinem Anwendungsfall. Am Ende habe ich die Quelle einfach so gefiltert (mit der Kurzschrift):
{
"_source": ["field_x", ..., "field_y"],
"query": {
...
}
}
Zu Ihrer Information, geben sie in der Dokumentation über die Felder Parameter:
Die get-Operation ermöglicht die Angabe einer Reihe gespeicherter Felder, die durch Übergabe des Feldparameters zurückgegeben werden.
Es scheint für speziell gespeicherte Felder zu sorgen, in denen jedes Feld in einem Array platziert wird. Wenn die angegebenen Felder nicht gespeichert wurden, werden alle Felder aus der _source abgerufen, was zu langsameren Abrufen führen kann. Ich hatte auch Probleme damit, Felder vom Typ Objekt zurückzugeben.
Zusammenfassend haben Sie also zwei Möglichkeiten, entweder durch Quellfilterung oder durch [gespeicherte] Felder.
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 ist der oben genannte Ansatz veraltet. Sie können den _source-Ansatz verwenden, aber in bestimmten Situationen kann es sinnvoll sein, ein Feld zu speichern. Wenn Sie beispielsweise ein Dokument mit einem Titel, einem Datum und einem sehr großen Inhaltsfeld haben, möchten Sie möglicherweise nur den Titel und das Datum abrufen, ohne diese Felder aus einem großen _source-Feld extrahieren zu müssen:
In diesem Fall würden Sie verwenden:
{
"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":{
}
}
Weitere Informationen zum Indizieren gespeicherter Felder finden Sie in der Dokumentation. Immer froh für ein Upvote!
Alle REST-APIs akzeptieren einen filter_path-Parameter, mit dem die von elasticsearch zurückgegebene Antwort reduziert werden kann. Dieser Parameter verwendet eine durch Kommas getrennte Liste von Filtern, die mit der Punktnotation ausgedrückt werden.
Hier eine andere Lösung, die jetzt einen Übereinstimmungsausdruck verwendet
Quelle Filterung
Ermöglicht zu kontrollieren , wie das _Source Feld bei jedem Treffer zurückgegeben.
Getestet mit Elastiscsearch Version 5.5
Das Schlüsselwort "enthält" definiert die spezifischen Felder.
GET /my_indice/my_indice_type/_search
{
"_source": {
"includes": [ "my_especific_field"]
},
"query": {
"bool": {
"must": [
{"match": {
"_id": "%my_id_here_without_percent%"
}
}
]
}
}
}
Eine REST-API-GET-Anforderung kann mit dem Parameter '_source' erfolgen.
Beispielanforderung
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
Antwort
{
"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
}
}
]
}
}}
Yes Quellenfilter verwenden Sie dies erreicht werden kann, ist hier die doc source-Filterung
Beispielanforderung
POST index_name/_search
{
"_source":["field1","filed2".....]
}
Ausgabe wird sein
{
"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 können Sie setFetchSource folgendermaßen verwenden:
client.prepareSearch(index).setTypes(type)
.setFetchSource(new String[] { "field1", "field2" }, null)
Sie haben beispielsweise ein Dokument mit drei Feldern:
PUT movie/_doc/1
{
"name":"The Lion King",
"language":"English",
"score":"9.3"
}
Wenn Sie zurückkehren möchten name
und score
den folgenden Befehl verwenden können:
GET movie/_doc/1?_source_includes=name,score
Wenn Sie einige Felder erhalten möchten, die einem Muster entsprechen:
GET movie/_doc/1?_source_includes=*re
Schließen Sie möglicherweise einige Felder aus:
GET movie/_doc/1?_source_excludes=score
Mit der Java-API verwende ich Folgendes, um alle Datensätze aus einer Reihe bestimmter Felder abzurufen:
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;
}