Buat elasticsearch hanya mengembalikan bidang tertentu?


Jawaban:


620

Ya! Gunakan filter sumber . Jika Anda mencari dengan JSON akan terlihat seperti ini:

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

Di ES 2.4 dan sebelumnya, Anda juga bisa menggunakan opsi bidang ke API pencarian :

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

Ini tidak digunakan lagi dalam ES 5+. Dan filter sumber lebih kuat!


12
pastikan untuk mendefinisikannya sebagai "tersimpan": benar dalam pemetaan. Kalau tidak, ES masih akan memuat dokumen sumber dan memuat bidang dari sana. Dapat berdampak kinerja jika data yang dikembalikan relatif kecil dengan ukuran seluruh dokumen.
Zaar Hai

6
Anda berarti "toko": true
sscarduzio

apakah ini dibuat di file conf atau di mana tepatnya?
vbNewbie

@vbNewbie: Di mana pun Anda mendefinisikan pemetaan. Jika Anda tidak mendefinisikan pemetaan secara eksplisit dan mengandalkan ES untuk menghasilkannya, maka Anda harus menentukan pemetaan untuk bidang yang ingin Anda simpan ES. Anda dapat menentukan pemetaan hanya untuk bidang yang Anda inginkan perilaku khusus (mis. "Store": true, "index": "not_analyzed") atau semua bidang. Lihatlah ke dokumen pemetaan untuk detail lebih lanjut.
Sangharsh

3
bidang tidak lagi didukung pada versi yang lebih baru. alih-alih gunakan stored_fields :)
Sachin Sharma

88

Saya menemukan dokumen untuk get apimembantu - terutama dua bagian, Penyaringan sumber dan Bidang : https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-get.html#get-source- penyaringan

Mereka menyatakan tentang pemfilteran sumber:

Jika Anda hanya membutuhkan satu atau dua bidang dari _source lengkap, Anda dapat menggunakan parameter _source_include & _source_exclude untuk menyertakan atau memfilter bagian yang Anda butuhkan. Ini dapat sangat membantu dengan dokumen besar di mana pengambilan sebagian dapat menghemat overhead jaringan

Yang pas dengan case saya. Saya akhirnya hanya memfilter sumber seperti itu (menggunakan singkatan):

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

FYI, mereka menyatakan dalam dokumen tentang parameter bidang :

Operasi dapatkan memungkinkan menentukan set bidang yang disimpan yang akan dikembalikan dengan melewati parameter bidang.

Tampaknya untuk memenuhi bidang yang telah disimpan secara khusus, di mana ia menempatkan masing-masing bidang dalam array. Jika bidang yang ditentukan belum disimpan, maka bidang tersebut akan diambil masing-masing dari sumber, yang dapat menyebabkan pengambilan lebih lambat. Saya juga mengalami kesulitan mencoba untuk mengembalikannya ke bidang tipe objek.

Jadi, secara ringkas, Anda memiliki dua opsi, baik pemfilteran sumber atau bidang [tersimpan].


Apakah trik untuk saya. Saya punya masalah dengan mengembalikan geo_point menggunakan "bidang", tetapi "_source" berfungsi dengan baik, terima kasih!
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

Dalam Elasticsearch 5.x pendekatan yang disebutkan di atas sudah usang. Anda bisa menggunakan pendekatan _source, tetapi tetapi dalam situasi tertentu masuk akal untuk menyimpan bidang. Misalnya, jika Anda memiliki dokumen dengan judul, tanggal, dan bidang konten yang sangat besar, Anda mungkin ingin mengambil hanya judul dan tanggal tanpa harus mengekstrak bidang tersebut dari bidang _source besar:

Dalam hal ini, Anda akan menggunakan:

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

   }
}

Lihat dokumentasi tentang cara mengindeks bidang yang disimpan. Selalu bahagia untuk Suara positif!


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

Permintaan REST API GET dapat dibuat dengan parameter '_source'.

Contoh Permintaan

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

Tanggapan

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

}


Ini sangat bermanfaat bagi saya.
Thusitha Indunil

4

Ya dengan menggunakan filter sumber Anda dapat melakukan ini, ini adalah pemfilteran sumber dokumen

Contoh Permintaan

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

Output akan menjadi

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

Di java, Anda bisa menggunakan setFetchSource seperti ini:

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

2

Misalnya, Anda memiliki dokumen dengan tiga bidang:

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

Jika Anda ingin kembali namedan scoreAnda dapat menggunakan perintah berikut:

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

Jika Anda ingin mendapatkan beberapa bidang yang cocok dengan pola:

GET movie/_doc/1?_source_includes=*re

Mungkin mengecualikan beberapa bidang:

GET movie/_doc/1?_source_excludes=score

0

Menggunakan Java API, saya menggunakan yang berikut ini untuk mendapatkan semua catatan dari sekumpulan bidang tertentu:

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;
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.