Lassen Sie elasticsearch nur bestimmte Felder zurückgeben?

434

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?

user1199438
quelle
1
elastic.co/guide/en/elasticsearch/reference/current/… , beachten Sie, dass Sie auch nur einige Felder ausschließen können
Christophe Roussy

Antworten:

619

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!

kevingessner
quelle
12
Stellen Sie sicher, dass Sie sie als "gespeichert" definieren: true in der Zuordnung. Andernfalls lädt ES weiterhin das _source-Dokument und die Felder von dort. Kann die Leistung beeinträchtigen, wenn die zurückgegebenen Daten relativ klein für die Größe eines gesamten Dokuments sind.
Zaar Hai
6
Sie meinten "speichern": true
sscarduzio
werden diese in der conf-Datei erstellt oder wo genau?
vbNewbie
@vbNewbie: Wo immer Sie Mapping definieren. Wenn Sie die Zuordnung nicht explizit definieren und sich beim Generieren auf ES verlassen, müssen Sie die Zuordnung für Felder definieren, in denen ES gespeichert werden soll. Sie können die Zuordnung nur für Felder definieren, in denen Sie ein spezielles Verhalten wünschen (z. B. "store": true, "index": "not_analyzed") oder für alle Felder. Weitere Informationen finden Sie in den Zuordnungsdokumenten.
Sangharsh
3
Felder werden in neueren Versionen nicht mehr unterstützt. benutze stattdessen gespeicherte Felder :)
Sachin Sharma
88

Ich fand die Dokumente get apihilfreich, 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.

Markus Coetzee
quelle
Hat den Trick für mich gemacht. Ich hatte ein Problem mit der Rückgabe von geo_point mithilfe von "fields", aber "_source" funktioniert einwandfrei, danke!
Yonnaled
23
For the ES versions 5.X and above you can a ES query something like this

    GET /.../...
    {
      "_source": {
        "includes": [ "FIELD1", "FIELD2", "FIELD3" ... " ]
      },
      .
      .
      .
      .
    }
Pinkesh Sharma
quelle
12

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!

Woltob
quelle
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" }
        }
    }
Gaurav
quelle
7

response_filtering

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.

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

Der Demz
quelle
5

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

}}

Ironluca
quelle
Das ist sehr nützlich für mich.
Thusitha Indunil
4

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

In Java können Sie setFetchSource folgendermaßen verwenden:

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

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 nameund scoreden 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
Yao Pan
quelle
0

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;
}
Doi
quelle