Belgelerimi dizine eklemek için elasticsearch kullanıyorum.
Sakladığı json belgesinin tamamı yerine yalnızca belirli alanları döndürmesi talimatı verilebilir mi?
Belgelerimi dizine eklemek için elasticsearch kullanıyorum.
Sakladığı json belgesinin tamamı yerine yalnızca belirli alanları döndürmesi talimatı verilebilir mi?
Yanıtlar:
Evet! Bir kaynak filtresi kullanın . JSON ile arama yapıyorsanız şöyle görünecektir:
{
"_source": ["user", "message", ...],
"query": ...,
"size": ...
}
ES 2.4 ve önceki sürümlerinde, arama API'sındaki alanlar seçeneğini de kullanabilirsiniz :
{
"fields": ["user", "message", ...],
"query": ...,
"size": ...
}
Bu ES 5+ 'da kullanımdan kaldırılmıştır. Ve kaynak filtreleri zaten daha güçlü!
Yardımcı olması için dokümanları buldum get api
- özellikle iki bölüm, Kaynak filtreleme ve Alanlar : https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-get.html#get-source- süzme
Kaynak filtrelemeyi belirtirler:
Komple _source öğesinden yalnızca bir veya iki alana ihtiyacınız varsa, ihtiyacınız olan parçaları dahil etmek veya filtrelemek için _source_include & _source_exclude parametrelerini kullanabilirsiniz. Bu özellikle kısmi alımın ağ yüküne tasarruf sağlayabileceği büyük belgelerde yardımcı olabilir
Hangi benim kullanım davayı mükemmel uydurdu. Ben sadece kaynak (böyle) steno filtre gibi sona erdi:
{
"_source": ["field_x", ..., "field_y"],
"query": {
...
}
}
Bilginize, belgelerde fields parametresi hakkında bilgi verir :
Get işlemi, fields parametresi iletilerek döndürülecek bir dizi saklı alan belirtilmesine izin verir.
Her alanı bir diziye yerleştirdiği, özel olarak depolanmış alanlara hitap ediyor gibi görünüyor. Belirtilen alanlar kaydedilmemişse, _source öğesinden her birini getirir, bu da 'daha yavaş' alımlara neden olabilir. Ayrıca tür nesne alanlarını döndürmek için çalışırken sorun vardı.
Özetle, kaynak filtreleme veya [depolanmış] alanlar olmak üzere iki seçeneğiniz vardır.
For the ES versions 5.X and above you can a ES query something like this
GET /.../...
{
"_source": {
"includes": [ "FIELD1", "FIELD2", "FIELD3" ... " ]
},
.
.
.
.
}
Elasticsearch 5.x'te yukarıda belirtilen yaklaşım kullanımdan kaldırılmıştır. _Source yaklaşımını kullanabilirsiniz, ancak bazı durumlarda bir alanı depolamak mantıklı olabilir. Örneğin, başlık, tarih ve çok geniş bir içerik alanına sahip bir belgeniz varsa, bu alanları büyük bir _source alanından çıkarmak zorunda kalmadan yalnızca başlığı ve tarihi almak isteyebilirsiniz:
Bu durumda şunları kullanırsınız:
{
"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":{
}
}
Depolanan alanların nasıl endeksleneceğine ilişkin belgelere bakın. Bir Olumlu Oy için her zaman mutlu!
Tüm REST API'leri, elasticsearch tarafından döndürülen yanıtı azaltmak için kullanılabilecek bir filter_path parametresini kabul eder. Bu parametre, nokta gösterimi ile ifade edilen, virgülle ayrılmış filtrelerin listesini alır.
İşte şimdi bir eşleşme ifadesi kullanan başka bir çözüm
Kaynak filtreleme
_source alanının her isabetle nasıl döndürüleceğini denetlemenizi sağlar.
Elastiscsearch sürüm 5.5 ile test edildi
"İçerir" anahtar kelimesi spesifikasyon alanlarını tanımlar.
GET /my_indice/my_indice_type/_search
{
"_source": {
"includes": [ "my_especific_field"]
},
"query": {
"bool": {
"must": [
{"match": {
"_id": "%my_id_here_without_percent%"
}
}
]
}
}
}
'_Source' parametresi ile bir REST API GET isteği yapılabilir.
Örnek İstek
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
Tepki
{
"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
}
}
]
}
}
Evet, kaynak filtreyi kullanarak bunu başarabilirsiniz, işte doc kaynak filtreleme
Örnek İstek
POST index_name/_search
{
"_source":["field1","filed2".....]
}
Çıktı
{
"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"
},....
}
]
}
}
Java'da setFetchSource'u şu şekilde kullanabilirsiniz:
client.prepareSearch(index).setTypes(type)
.setFetchSource(new String[] { "field1", "field2" }, null)
Örneğin, üç alana sahip bir dokümanınız var:
PUT movie/_doc/1
{
"name":"The Lion King",
"language":"English",
"score":"9.3"
}
Eğer dönmek isterseniz name
ve score
aşağıdaki komutu kullanabilirsiniz:
GET movie/_doc/1?_source_includes=name,score
Bir desenle eşleşen bazı alanlar elde etmek istiyorsanız:
GET movie/_doc/1?_source_includes=*re
Belki bazı alanları hariç tutun:
GET movie/_doc/1?_source_excludes=score
Java API kullanarak, bir dizi belirli alandan tüm kayıtları almak için aşağıdakileri kullanın:
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;
}