web-dev-qa-db-fra.com

Faire elasticsearch ne renvoyer que certains champs?

J'utilise elasticsearch pour indexer mes documents.

Est-il possible de lui demander de ne renvoyer que des champs particuliers au lieu du document JSON entier qu'il a stocké?

360
user1199438

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

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

Dans ES 2.4 et les 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 de source sont quand même plus puissants!

498
kevingessner

J'ai trouvé la documentation pour le get api utile, notamment les deux sections Filtrage de la source et Champs : - https://www.elastic.co/guide/fr/elasticsearch/reference/7.3/docs-get.html#get-source-filtering

Ils déclarent à propos du filtrage de source:

Si vous n'avez besoin que d'un ou deux champs de la source complète _source, 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 pour les documents volumineux où la récupération partielle peut réduire les frais généraux du réseau.

Ce qui convenait parfaitement à mon cas d'utilisation. J'ai fini par filtrer simplement la source comme suit (en utilisant le raccourci):

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

Pour votre information, ils indiquent dans la documentation à propos du paramètre field :

L'opération get permet de spécifier un ensemble de champs stockés qui seront renvoyé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, chacun d'eux sera extrait de la source _source, ce qui pourrait entraîner des extractions 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 le filtrage de la source, soit les champs [stockés].

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

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

Dans Elasticsearch 5.x, l'approche susmentionnée est obsolète. 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 très grand champ de contenu, vous pouvez extraire uniquement le titre et la date sans avoir à extraire ces champs d'un gros 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":{  

   }
}

Voir la documentation sur la façon d'indexer les champs stockés. Toujours heureux pour un vote positif!

10
woltob

filtre_réponse

Toutes les API REST acceptent un paramètre filter_path pouvant être utilisé pour réduire la réponse renvoyée par elasticsearch. Ce paramètre prend une liste de filtres séparés par des virgules, exprimés avec la notation par points.

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

7
The Demz

Voici une autre solution, utilisant maintenant une expression correspondante

filtrage de la source
Permet de contrôler la manière dont le champ _source est renvoyé à chaque hit.

Testé avec Elastiscsearch version 5.5

Le mot clé "includes" définit les champs spécifiques.

GET /my_indice/my_indice_type/_search
{
    "_source": {
        "includes": [ "my_especific_field"]
        },
        "query": {
        "bool": {
                "must": [
                {"match": {
                    "_id": "%my_id_here_without_percent%"
                    }
                }
            ]
        }
    }
}
6
Fabricio
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" }
        }
    }
6
Gaurav

Une requête 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
            }
        }
    ]
}

}

4
Ironluca

Dans Java, vous pouvez utiliser setFetchSource comme ceci:

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

Oui, en utilisant le filtre source, vous pouvez le faire, voici la doc filtrage par la source

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
RCP

Par exemple, vous avez un doc avec trois champs:

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

si vous voulez retourner name et score, vous pouvez utiliser la commande suivante:

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

Si vous voulez obtenir un champ avec un motif:

GET moive/_doc/1?_source_includes=*re

Peut-être sauf quelques champs:

GET moive/_doc/1?_source_excludes=score
0
Yao Pan