Lassen Sie elasticsearch nur bestimmte Felder zurückgeben?


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!


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.


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

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!


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

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

}}


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

2

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

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

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

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;
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.