Elasticsearch 2.1: หน้าต่างผลลัพธ์ใหญ่เกินไป (index.max_result_window)


88

เราดึงข้อมูลจาก Elasticsearch 2.1 และอนุญาตให้ผู้ใช้ไปยังหน้าผ่านผลลัพธ์ เมื่อผู้ใช้ร้องขอหมายเลขหน้าสูงเราจะได้รับข้อความแสดงข้อผิดพลาดต่อไปนี้:

หน้าต่างผลลัพธ์ใหญ่เกินไปขนาดจาก + ต้องน้อยกว่าหรือเท่ากับ: [10000] แต่สูงกว่า [10020] ดู scroll api สำหรับวิธีที่มีประสิทธิภาพมากขึ้นในการร้องขอชุดข้อมูลขนาดใหญ่ ขีด จำกัด นี้สามารถกำหนดได้โดยการเปลี่ยนพารามิเตอร์ระดับดัชนี [index.max_result_window]

docu ยืดหยุ่นบอกว่านี่เป็นเพราะการใช้หน่วยความจำสูงและใช้ API การเลื่อน:

ค่าที่สูงกว่าที่สามารถใช้หน่วยความจำฮีปจำนวนมากต่อการค้นหาและต่อชาร์ดที่ดำเนินการค้นหา ปลอดภัยที่สุดที่จะปล่อยให้ค่านี้เนื่องจากเป็นการใช้ scroll api สำหรับการเลื่อนแบบลึก ๆhttps://www.elastic.co/guide/en/elasticsearch/reference/2.x/breaking_21_search_changes.html#_from_size_limits

สิ่งนี้คือฉันไม่ต้องการดึงชุดข้อมูลขนาดใหญ่ ฉันต้องการดึงข้อมูลชิ้นส่วนจากชุดข้อมูลซึ่งสูงมากในชุดผลลัพธ์เท่านั้น นอกจากนี้ docu แบบเลื่อนยังบอกว่า:

การเลื่อนไม่ได้มีไว้สำหรับคำขอของผู้ใช้แบบเรียลไทม์https://www.elastic.co/guide/en/elasticsearch/reference/2.2/search-request-scroll.html

สิ่งนี้ทำให้ฉันมีคำถาม:

1) การใช้หน่วยความจำจะลดลงจริงๆหรือไม่ (ถ้าเป็นเช่นนั้นเพราะเหตุใด) ถ้าฉันใช้ scrolling api เพื่อเลื่อนขึ้นไปที่ผลลัพธ์ 10020 (และไม่สนใจทุกอย่างที่ต่ำกว่า 10,000) แทนที่จะทำคำขอค้นหา "ปกติ" สำหรับผลลัพธ์ 10,000-10020

2) ดูเหมือนว่า API การเลื่อนจะไม่ใช่ทางเลือกสำหรับฉัน แต่ฉันต้องเพิ่ม "index.max_result_window" ใครมีประสบการณ์เกี่ยวกับเรื่องนี้บ้าง?

3) มีตัวเลือกอื่นในการแก้ปัญหาของฉันหรือไม่?

คำตอบ:


80

max_result_windowหากคุณต้องการเลขลึกวิธีการแก้ปัญหาที่เป็นไปได้คือการเพิ่มมูลค่า คุณสามารถใช้curlเพื่อทำสิ่งนี้จากบรรทัดคำสั่งเชลล์ของคุณ:

curl -XPUT "http://localhost:9200/my_index/_settings" -H 'Content-Type: application/json' -d '{ "index" : { "max_result_window" : 500000 } }'

ฉันไม่สังเกตเห็นการใช้หน่วยความจำที่เพิ่มขึ้นสำหรับค่า ~ 100k


ฉันมีข้อผิดพลาดเดียวกัน'Result window is too large, from + size must be less than or equal to: [10000] but was [47190]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level parameter.')มันบอกว่ามี 4719 หน้า (ทุกหน้า 10 ผลลัพธ์) และฉันคิดว่าคำแนะนำของคุณใช้ได้ผล
dotslash

1
นี่เป็นทางออกที่ดีสำหรับเอกสารจำนวนน้อยที่น้อยกว่า 500000
Ezzat

2
ฉันใช้ ES v2.2.0 และฉันต้องเปลี่ยนเพย์โหลดเพื่อ{ "max_result_window" : 500000 }ให้มันใช้งานได้ ดังนั้นคำสั่ง curl จึงกลายเป็น -curl -XPUT "http://localhost:9200/my_index/_settings" -d '{ "max_result_window" : 500000 }'
Parin Porecha

3
สำหรับผู้ที่ได้รับข้อผิดพลาดส่วนหัวด้วยคำสั่งนี้สำหรับ elasticsearch เวอร์ชันใหม่กว่าคุณจะต้องส่งส่วนหัวด้วยเช่นกัน curl -XPUT " localhost: 9200 / my_index / _settings " -H "Content-Type: application / json" -d '{ "index": {"max_result_window": 50000}} "
Satys

32

ทางออกที่เหมาะสมคือการใช้การเลื่อน
อย่างไรก็ตามหากคุณต้องการขยายผลลัพธ์searchให้ได้มากกว่า 10,000 ผลลัพธ์คุณสามารถทำได้ง่ายๆด้วย Kibana:

ไปที่Dev Toolsและโพสต์สิ่งต่อไปนี้ในดัชนีของคุณ (your_index_name) โดยระบุว่าจะเป็นหน้าต่างผลลัพธ์สูงสุดใหม่

ป้อนคำอธิบายภาพที่นี่

PUT your_index_name/_settings
{ 
  "max_result_window" : 500000 
}

หากทุกอย่างเป็นไปด้วยดีคุณควรเห็นการตอบสนองความสำเร็จดังต่อไปนี้:

{
  "acknowledged": true
}

1
ฉันลองทำตามวิธีนี้ในรหัส elasticsearch (put_settings เป็นต้น .. ) และพบข้อผิดพลาดมากมาย ประหยัดเวลาได้หลายชั่วโมง! ขอขอบคุณ!
cpres

25

หน้าต่อไปนี้ในเอกสารคู่มือแบบยืดหยุ่นพูดถึงการเพจแบบลึก:

https://www.elastic.co/guide/en/elasticsearch/guide/current/pagination.html https://www.elastic.co/guide/en/elasticsearch/guide/current/_fetch_phase.html

ขึ้นอยู่กับขนาดของเอกสารของคุณจำนวนชิ้นส่วนและฮาร์ดแวร์ที่คุณใช้การเพจ 10,000 ถึง 50,000 ผลลัพธ์ (1,000 ถึง 5,000 หน้า) ควรทำได้อย่างสมบูรณ์แบบ แต่ด้วยค่าที่มากพอกระบวนการจัดเรียงอาจจะหนักมากโดยใช้ CPU หน่วยความจำและแบนด์วิดท์จำนวนมหาศาล ด้วยเหตุนี้เราจึงไม่แนะนำอย่างยิ่งให้ไม่ต้องมีการเพจลึก


1
ตรงนี้เราควรละทิ้งการแบ่งเลขหน้าลึกใช่ไหม? โดยทั่วไปไม่มีความหมายของการเพจ 4000 เพจสำหรับวิวเวอร์เดียว สมมติว่าการค้นหาของ Google แทบจะไม่เลื่อนไปที่หน้า 8 หรือ 9 เพื่อตรวจสอบผลลัพธ์ โดยปกติเราจะดูแลเพียง 3-5 หน้าแรกที่ Google ให้เราเท่านั้น
dotslash

2
เราสามารถใช้ scroll API ได้ไหมในกรณีที่เราต้องการการแบ่งหน้าแบบลึก
Abhi.G

3
แต่เมื่อเราเปิดใช้งานคุณลักษณะการจัดเรียงให้พูดบนไซต์อีคอมเมิร์ซ เมื่อผู้ใช้ต้องการดูรายการที่มีราคาสูงสุด ผลลัพธ์จะแตกต่างกันเมื่อเราจัดเรียงตามราคาสูงสุดเปรียบเทียบกับเมื่อเราเรียงตามหน้าต่ำสุด แต่ไปที่หน้าสุดท้ายใช่ไหม เนื่องจากเรา จำกัด จำนวนผลลัพธ์ที่สามารถเข้าถึงได้ วิธีแก้ปัญหานี้หรือไม่
MR Murazza

3

ใช้ Scroll API เพื่อรับผลลัพธ์มากกว่า 10,000 รายการ

ตัวอย่างการเลื่อนใน ElasticSearch NEST API

ฉันใช้มันแบบนี้:

private static Customer[] GetCustomers(IElasticClient elasticClient)
{
    var customers = new List<Customer>();
    var searchResult = elasticClient.Search<Customer>(s => s.Index(IndexAlias.ForCustomers())
                          .Size(10000).SearchType(SearchType.Scan).Scroll("1m"));

    do
    {
        var result = searchResult;
        searchResult = elasticClient.Scroll<Customer>("1m", result.ScrollId);
        customers.AddRange(searchResult.Documents);
    } while (searchResult.IsValid && searchResult.Documents.Any());

    return customers.ToArray();
}

0

หากคุณต้องการผลลัพธ์มากกว่า 10,000 รายการในโหนดข้อมูลทั้งหมดการใช้หน่วยความจำจะสูงมากเนื่องจากต้องส่งคืนผลลัพธ์มากขึ้นในการร้องขอการสืบค้นแต่ละครั้ง จากนั้นหากคุณมีข้อมูลมากขึ้นและมีเศษมากขึ้นการรวมผลลัพธ์เหล่านั้นก็จะไม่มีประสิทธิภาพ นอกจากนี้ยังแคชบริบทตัวกรองดังนั้นหน่วยความจำจึงเพิ่มขึ้นอีกครั้ง คุณต้องลองผิดลองถูกว่าคุณรับไหวแค่ไหน หากคุณได้รับคำขอจำนวนมากในหน้าต่างเล็ก ๆ คุณควรทำแบบสอบถามมากกว่า 10,000 รายการและรวมเข้าด้วยกันโดย urself ในรหัสซึ่งควรจะใช้หน่วยความจำแอปพลิเคชันน้อยลงหากคุณเพิ่มขนาดหน้าต่าง


0

2) ดูเหมือนว่า API การเลื่อนจะไม่ใช่ทางเลือกสำหรับฉัน แต่ฉันต้องเพิ่ม "index.max_result_window" ใครมีประสบการณ์เกี่ยวกับเรื่องนี้บ้าง?

-> คุณสามารถกำหนดค่านี้ในเทมเพลตดัชนีเทมเพลต es จะใช้ได้กับดัชนีใหม่เท่านั้นดังนั้นคุณต้องลบดัชนีเก่าหลังจากสร้างเทมเพลตหรือรอให้นำเข้าข้อมูลใหม่ใน elasticsearch

{"order": 1, "template": "index_template *", "settings": {"index.number_of_replicas": "0", "index.number_of_shards": "1", "index.max_result_window": 2147483647},


0

ในกรณีของฉันดูเหมือนว่าการลดผลลัพธ์ผ่านคำนำหน้าจาก & ขนาดในแบบสอบถามจะลบข้อผิดพลาดเนื่องจากเราไม่ต้องการผลลัพธ์ทั้งหมด:

GET widgets_development/_search
{
  "from" : 0, 
  "size": 5,
  "query": {
    "bool": {}
  },
  "sort": {
    "col_one": "asc"
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.