ฉันใช้ elasticsearch เพื่อจัดทำดัชนีเอกสารของฉัน
เป็นไปได้ไหมที่จะสั่งให้ส่งคืนเฉพาะบางฟิลด์แทนที่จะเป็นเอกสาร json ทั้งหมดที่เก็บไว้?
ฉันใช้ elasticsearch เพื่อจัดทำดัชนีเอกสารของฉัน
เป็นไปได้ไหมที่จะสั่งให้ส่งคืนเฉพาะบางฟิลด์แทนที่จะเป็นเอกสาร json ทั้งหมดที่เก็บไว้?
คำตอบ:
อ้อ! ใช้ตัวกรองที่มา หากคุณกำลังค้นหาด้วย JSON มันจะมีลักษณะดังนี้:
{
"_source": ["user", "message", ...],
"query": ...,
"size": ...
}
ใน ES 2.4 และรุ่นก่อนหน้าคุณสามารถใช้ตัวเลือกฟิลด์กับ API การค้นหา :
{
"fields": ["user", "message", ...],
"query": ...,
"size": ...
}
เลิกใช้แล้วใน ES 5+ และแหล่งตัวกรองมีประสิทธิภาพมากขึ้นต่อไป!
ฉันพบเอกสารที่get api
จะเป็นประโยชน์โดยเฉพาะอย่างยิ่งในสองส่วนคือการกรองแหล่งที่มาและฟิลด์ : https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-get.html#get-source- กรอง
พวกเขาระบุเกี่ยวกับการกรองแหล่งที่มา:
หากคุณต้องการเพียงหนึ่งหรือสองฟิลด์จาก _source ที่สมบูรณ์คุณสามารถใช้พารามิเตอร์ _source_include & _source_exclude เพื่อรวมหรือกรองส่วนที่คุณต้องการ สิ่งนี้มีประโยชน์อย่างยิ่งกับเอกสารขนาดใหญ่ที่การดึงข้อมูลบางส่วนสามารถประหยัดค่าใช้จ่ายบนเครือข่าย
ซึ่งเหมาะกับกรณีการใช้งานของฉันอย่างสมบูรณ์แบบ ฉันลงเอยด้วยการกรองแหล่งที่มาเช่นนั้น (โดยใช้ชวเลข):
{
"_source": ["field_x", ..., "field_y"],
"query": {
...
}
}
FYI พวกเขาระบุในเอกสารเกี่ยวกับพารามิเตอร์ฟิลด์ :
การดำเนินการ get อนุญาตให้ระบุชุดของฟิลด์ที่เก็บไว้ซึ่งจะถูกส่งคืนโดยส่งผ่านพารามิเตอร์ฟิลด์
ดูเหมือนว่าจะตอบสนองสำหรับเขตข้อมูลที่ถูกเก็บไว้โดยเฉพาะที่มันวางแต่ละเขตข้อมูลในอาร์เรย์ หากไม่ได้เก็บฟิลด์ที่ระบุไว้ฟิลด์นั้นจะดึงข้อมูลแต่ละฟิลด์จาก _source ซึ่งอาจทำให้การดึงข้อมูล 'ช้าลง' ฉันยังมีปัญหาในการพยายามให้มันคืนค่าฟิลด์ประเภทวัตถุ
ดังนั้นโดยสรุปคุณมีสองตัวเลือกไม่ว่าจะเป็นการกรองแหล่งข้อมูลหรือ [เก็บไว้]
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 วิธีการที่กล่าวถึงข้างต้นถูกคัดค้าน คุณสามารถใช้วิธี _source ได้ แต่ในบางสถานการณ์อาจใช้วิธีจัดเก็บฟิลด์ ตัวอย่างเช่นหากคุณมีเอกสารที่มีชื่อเรื่องวันที่และฟิลด์เนื้อหาที่มีขนาดใหญ่มากคุณอาจต้องการดึงเฉพาะชื่อและวันที่โดยไม่ต้องแยกฟิลด์เหล่านั้นออกจากฟิลด์ _source ขนาดใหญ่:
ในกรณีนี้คุณจะใช้:
{
"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":{
}
}
ดูเอกสารประกอบเกี่ยวกับวิธีสร้างดัชนีฟิลด์ที่จัดเก็บ มีความสุขเสมอสำหรับการโหวต!
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" }
}
}
REST APIs ทั้งหมดยอมรับพารามิเตอร์ filter_path ที่สามารถใช้เพื่อลดการตอบกลับที่ส่งกลับโดย elasticsearch พารามิเตอร์นี้ใช้รายการของตัวกรองที่คั่นด้วยเครื่องหมายจุลภาคที่แสดงด้วยเครื่องหมายจุด
นี่คือวิธีแก้ไขปัญหาอื่นตอนนี้ใช้นิพจน์การ แข่งขัน
การกรองแหล่งที่มา
ช่วยให้สามารถควบคุมวิธีการส่งคืนฟิลด์ _source ในทุก Hit
ทดสอบกับ Elastiscsearch เวอร์ชั่น 5.5
คำหลัก"รวมถึง"กำหนดเขตข้อมูลเฉพาะ
GET /my_indice/my_indice_type/_search
{
"_source": {
"includes": [ "my_especific_field"]
},
"query": {
"bool": {
"must": [
{"match": {
"_id": "%my_id_here_without_percent%"
}
}
]
}
}
}
คำขอ REST API GET สามารถทำได้ด้วยพารามิเตอร์ '_source'
ตัวอย่างคำขอ
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
คำตอบ
{
"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
}
}
]
}
}
ใช่โดยใช้ตัวกรองแหล่งที่มาคุณสามารถทำได้นี่คือ doc -filter source
ตัวอย่างคำขอ
POST index_name/_search
{
"_source":["field1","filed2".....]
}
ผลผลิตจะได้
{
"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 คุณสามารถใช้ setFetchSource เช่นนี้:
client.prepareSearch(index).setTypes(type)
.setFetchSource(new String[] { "field1", "field2" }, null)
ตัวอย่างเช่นคุณมีเอกสารที่มีสามฟิลด์:
PUT movie/_doc/1
{
"name":"The Lion King",
"language":"English",
"score":"9.3"
}
หากคุณต้องการส่งคืนname
และscore
คุณสามารถใช้คำสั่งต่อไปนี้:
GET movie/_doc/1?_source_includes=name,score
หากคุณต้องการรับบางฟิลด์ที่ตรงกับรูปแบบ:
GET movie/_doc/1?_source_includes=*re
อาจยกเว้นบางฟิลด์:
GET movie/_doc/1?_source_excludes=score
ใช้ Java API ฉันใช้ต่อไปนี้เพื่อรับระเบียนทั้งหมดจากชุดของเขตข้อมูลเฉพาะ:
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;
}