Saya menggunakan elasticsearch untuk mengindeks dokumen saya.
Apakah mungkin untuk menginstruksikannya hanya mengembalikan bidang tertentu dan bukan seluruh dokumen json yang telah disimpannya?
Saya menggunakan elasticsearch untuk mengindeks dokumen saya.
Apakah mungkin untuk menginstruksikannya hanya mengembalikan bidang tertentu dan bukan seluruh dokumen json yang telah disimpannya?
Jawaban:
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!
Saya menemukan dokumen untuk get api
membantu - 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].
For the ES versions 5.X and above you can a ES query something like this
GET /.../...
{
"_source": {
"includes": [ "FIELD1", "FIELD2", "FIELD3" ... " ]
},
.
.
.
.
}
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!
Semua API REST menerima parameter filter_path yang dapat digunakan untuk mengurangi respons yang dikembalikan oleh elasticsearch. Parameter ini mengambil daftar filter yang dipisahkan koma yang dinyatakan dengan notasi titik.
Di sini solusi lain, sekarang menggunakan ekspresi kecocokan
Diuji dengan Elastiscsearch versi 5.5
Kata kunci "termasuk" mendefinisikan bidang spesifik.
GET /my_indice/my_indice_type/_search
{
"_source": {
"includes": [ "my_especific_field"]
},
"query": {
"bool": {
"must": [
{"match": {
"_id": "%my_id_here_without_percent%"
}
}
]
}
}
}
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
}
}
]
}
}
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"
},....
}
]
}
}
Di java, Anda bisa menggunakan setFetchSource seperti ini:
client.prepareSearch(index).setTypes(type)
.setFetchSource(new String[] { "field1", "field2" }, null)
Misalnya, Anda memiliki dokumen dengan tiga bidang:
PUT movie/_doc/1
{
"name":"The Lion King",
"language":"English",
"score":"9.3"
}
Jika Anda ingin kembali name
dan score
Anda 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
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;
}