¿Hacer elasticsearch solo devuelve ciertos campos?

Respuestas:

620

¡Sí! Usa un filtro fuente . Si está buscando con JSON, se verá así:

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

En ES 2.4 y versiones anteriores, también podría usar la opción de campos para la API de búsqueda :

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

Esto está en desuso en ES 5+. ¡Y los filtros fuente son más potentes de todos modos!

kevingessner
fuente
12
asegúrese de definirlos como "almacenados": verdadero en el mapeo. De lo contrario, ES aún cargará el documento fuente y cargará los campos desde allí. Puede afectar el rendimiento si los datos devueltos son relativamente pequeños al tamaño de un documento completo.
Zaar Hai
66
querías
¿están hechos en el archivo conf o dónde exactamente?
vbNewbie
@vbNewbie: Donde sea que estés definiendo el mapeo. Si no está definiendo el mapeo explícitamente y no depende de ES para generarlo, entonces tendrá que definir el mapeo para los campos que desea que ES almacene. Puede definir la asignación solo para los campos donde desea un comportamiento especial (por ejemplo, "tienda": verdadero, "índice": "no_analizado") o todos los campos. Mire los documentos de mapeo para más detalles.
Sangharsh
3
campos ya no es compatible con las versiones más recientes. use almacenados_campos en su lugar :)
Sachin Sharma
88

Encontré los documentos para get apique sean útiles, especialmente las dos secciones, Filtrado de origen y Campos : https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-get.html#get-source- filtración

Afirman sobre el filtrado de origen:

Si solo necesita uno o dos campos del _source completo, puede usar los parámetros _source_include y _source_exclude para incluir o filtrar las partes que necesita. Esto puede ser especialmente útil con documentos grandes donde la recuperación parcial puede ahorrar en la sobrecarga de la red

Lo cual se ajustaba perfectamente a mi caso de uso. Terminé simplemente filtrando la fuente así (usando la abreviatura):

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

Para su información, indican en los documentos sobre el parámetro de campos :

La operación get permite especificar un conjunto de campos almacenados que se devolverán al pasar el parámetro de los campos.

Parece atender los campos que se han almacenado específicamente, donde coloca cada campo en una matriz. Si los campos especificados no se han almacenado, obtendrá cada uno de _source, lo que podría resultar en recuperaciones 'más lentas'. También tuve problemas para intentar que devolviera campos de tipo objeto.

En resumen, tiene dos opciones, ya sea mediante el filtrado de origen o los campos [almacenados].

Markus Coetzee
fuente
Hizo el truco para mí. Tuve un problema al devolver geo_point usando "fields", pero "_source" funciona bien, ¡gracias!
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
fuente
12

En Elasticsearch 5.x, el enfoque mencionado anteriormente está en desuso. Puede usar el enfoque _source, pero en ciertas situaciones puede tener sentido almacenar un campo. Por ejemplo, si tiene un documento con un título, una fecha y un campo de contenido muy grande, es posible que desee recuperar solo el título y la fecha sin tener que extraer esos campos de un campo _source grande:

En este caso, usarías:

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

   }
}

Consulte la documentación sobre cómo indexar los campos almacenados. ¡Siempre feliz por un voto a favor!

Woltob
fuente
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
fuente
5

Se podría realizar una solicitud REST API GET con el parámetro '_source'.

Solicitud de ejemplo

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

Respuesta

{
"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
fuente
Esto es muy útil para mí.
Así, Indunil, el
4

Sí, mediante el uso del filtro fuente puede lograr esto, aquí está el filtro fuente de documentos

Solicitud de ejemplo

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

La salida será

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

En java puedes usar setFetchSource de esta manera:

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

Por ejemplo, tiene un documento con tres campos:

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

Si desea regresar namey scorepuede usar el siguiente comando:

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

Si desea obtener algunos campos que coinciden con un patrón:

GET movie/_doc/1?_source_includes=*re

Quizás excluir algunos campos:

GET movie/_doc/1?_source_excludes=score
Yao Pan
fuente
0

Con la API de Java, uso lo siguiente para obtener todos los registros de un conjunto de campos particulares:

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
fuente