Faire elasticsearch ne renvoie que certains champs?


Réponses:


620

Oui! Utilisez un filtre source . Si vous recherchez avec JSON, cela ressemblera à ceci:

{
    "_source": ["user", "message", ...],
    "query": ...,
    "size": ...
}

Dans ES 2.4 et versions antérieures, vous pouvez également utiliser l' option champs de l'API de recherche :

{
    "fields": ["user", "message", ...],
    "query": ...,
    "size": ...
}

Ceci est déconseillé dans ES 5+. Et les filtres sources sont de toute façon plus puissants!


12
assurez-vous de les définir comme "stockés": vrai dans le mappage. Sinon, ES chargera toujours le document _source et chargera les champs à partir de là. Peut affecter les performances si les données renvoyées sont relativement petites par rapport à la taille d'un document entier.
Zaar Hai

6
vous vouliez dire "magasin": vrai
sscarduzio

sont-ils faits dans le fichier conf ou où exactement?
vbNewbie

@vbNewbie: Où que vous définissiez la cartographie. Si vous ne définissez pas le mappage de manière explicite et ne comptez pas sur ES pour le générer, vous devrez définir le mappage pour les champs que vous souhaitez que ES stocke. Vous pouvez définir le mappage uniquement pour les champs pour lesquels vous souhaitez un comportement spécial (par exemple, "store": true, "index": "not_analyzed") ou tous les champs. Consultez les documents de mappage pour plus de détails.
Sangharsh

3
champs n'est plus pris en charge sur les versions plus récentes. utilisez plutôt stored_fields :)
Sachin Sharma

88

J'ai trouvé les documents get apiutiles pour - en particulier les deux sections, Filtrage des sources et Champs : https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-get.html#get-source- filtration

Ils déclarent sur le filtrage des sources:

Si vous n'avez besoin que d'un ou deux champs de la _source complète, vous pouvez utiliser les paramètres _source_include & _source_exclude pour inclure ou filtrer les pièces dont vous avez besoin. Cela peut être particulièrement utile avec des documents volumineux où la récupération partielle peut économiser sur la surcharge du réseau

Ce qui correspondait parfaitement à mon cas d'utilisation. J'ai fini par simplement filtrer la source comme ça (en utilisant la sténographie):

{
    "_source": ["field_x", ..., "field_y"],
    "query": {      
        ...
    }
}

Pour info, ils déclarent dans la documentation sur le paramètre champs :

L'opération get permet de spécifier un ensemble de champs stockés qui seront retournés en passant le paramètre fields.

Il semble répondre aux champs qui ont été spécifiquement stockés, où il place chaque champ dans un tableau. Si les champs spécifiés n'ont pas été stockés, ils seront récupérés chacun à partir de la source _, ce qui pourrait entraîner des récupérations «plus lentes». J'ai également eu du mal à le faire renvoyer des champs de type objet.

Donc, en résumé, vous avez deux options, soit par filtrage de source, soit par champs [stockés].


A fait l'affaire pour moi. J'ai eu un problème avec le retour de geo_point en utilisant "champs", mais "_source" fonctionne très bien, merci!
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

Dans Elasticsearch 5.x, l'approche mentionnée ci-dessus est déconseillée. Vous pouvez utiliser l'approche _source, mais dans certaines situations, il peut être judicieux de stocker un champ. Par exemple, si vous avez un document avec un titre, une date et un champ de contenu très volumineux, vous souhaiterez peut-être récupérer uniquement le titre et la date sans avoir à extraire ces champs d'un grand champ _source:

Dans ce cas, vous utiliseriez:

{  
   "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":{  

   }
}

Consultez la documentation sur l'indexation des champs stockés. Toujours heureux pour un 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

Une demande REST API GET peut être effectuée avec le paramètre '_source'.

Exemple de demande

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

Réponse

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

}


C'est très complet pour moi.
Thusitha Indunil

4

Oui, en utilisant le filtre source, vous pouvez accomplir cela, voici le doc source-filtering

Exemple de demande

POST index_name/_search
 {
   "_source":["field1","filed2".....] 
 }

La sortie sera

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

En java, vous pouvez utiliser setFetchSource comme ceci:

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

2

Par exemple, vous avez un document avec trois champs:

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

Si vous souhaitez revenir nameet scorevous pouvez utiliser la commande suivante:

GET movie/_doc/1?_source_includes=name,score

Si vous souhaitez obtenir des champs qui correspondent à un modèle:

GET movie/_doc/1?_source_includes=*re

Peut-être exclure certains champs:

GET movie/_doc/1?_source_excludes=score

0

En utilisant l'API Java, j'utilise ce qui suit pour obtenir tous les enregistrements d'un ensemble de champs particuliers:

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;
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.