การค้นหาคนกลางโดยใช้ LunrJS
เพิ่มบรรทัดนี้ลงใน Gemfile ของแอปพลิเคชันของคุณ:
gem 'middleman-search'
แล้วดำเนินการ:
$ bundle
หรือติดตั้งด้วยตัวเองเป็น:
$ gem install middleman-search
คุณต้องเปิดใช้งานโมดูลใน config.rb
ของคุณ โดยบอกส่วนขยายว่าจะจัดทำดัชนีทรัพยากรของคุณอย่างไร:
activate :search do | search |
search . resources = [ 'blog/' , 'index.html' , 'contactus/index.html' ]
search . index_path = 'search/lunr-index.json' # defaults to `search.json`
search . lunr_dirs = [ 'source/vendor/lunr-custom/' ] # optional alternate paths where to look for lunr js files
search . language = 'es' # defaults to 'en'
search . fields = {
title : { boost : 100 , store : true , required : true } ,
content : { boost : 50 } ,
url : { index : false , store : true } ,
author : { boost : 30 }
}
end
โดยที่ resources
คือรายการจุดเริ่มต้นของ URL ของทรัพยากรที่จะจัดทำดัชนี (ทดสอบด้วย String#start_with?
) index_path
คือเส้นทางสัมพัทธ์ของไฟล์ดัชนีที่สร้างขึ้นในไซต์ของคุณ และ fields
เป็นแฮชที่มีหนึ่งรายการสำหรับแต่ละฟิลด์ ที่จะจัดทำดัชนี พร้อมด้วยแฮชของตัวเลือกที่เกี่ยวข้อง:
boost
ระบุการเพิ่มความเกี่ยวข้อง lunr เมื่อค้นหาฟิลด์นี้store
ว่าจะจัดเก็บฟิลด์นี้ในแผนผังเอกสารหรือไม่ (ดูด้านล่าง) ค่าเริ่มต้นเป็นเท็จindex
ว่าจะจัดทำดัชนีฟิลด์นี้หรือไม่ ค่าเริ่มต้นเป็นจริงrequired
ทรัพยากรจะไม่ถูกจัดทำดัชนีหากฟิลด์ที่ทำเครื่องหมายว่าจำเป็นมีค่าว่างหรือค่าว่าง โปรดทราบว่า id
ฟิลด์พิเศษจะถูกรวมไว้โดยอัตโนมัติ โดยมีตัวระบุที่สร้างขึ้นอัตโนมัติเพื่อใช้เป็นข้อมูล ref
สำหรับเอกสาร
ค่าของฟิลด์ทั้งหมดจะถูกดึงมาจาก data
ทรัพยากร (เช่น ส่วนหน้า) หรือจาก options
ใน resource.metadata
(เช่น ตัวเลือกใดๆ ที่ระบุในหน้า proxy
) ยกเว้น:
url
ซึ่งเป็น URL ทรัพยากรจริงcontent
ข้อความที่ดึงมาจากทรัพยากรที่แสดงผล โดยไม่รวมถึงเค้าโครง จากนั้นคุณสามารถสืบค้นดัชนีจาก Javascript ผ่านวัตถุ lunrIndex
(ดูไฟล์ดัชนีสำหรับข้อมูลเพิ่มเติม):
var max_search_entries = 50 ;
var result = [ ] ; //initialize empty array
lunrIndex . search ( request . term ) . forEach ( function ( item , index ) {
if ( index < max_search_entries ) {
result . push ( lunrData . docs [ item . ref ] ) ;
}
} ) ;
(ขอบคุณ @Jeepler ที่ปรับโค้ด lodash v3 ที่เราเคยใช้ที่ Manas)
อัญมณีนี้รวมเนื้อหาสำหรับภาษาอื่นตามที่ MihaiValentin/lunr- languages ให้ไว้ โปรดดูที่พื้นที่เก็บข้อมูลนั้นเพื่อดูรายการภาษาที่มี
หากคุณต้องการทำงานกับภาษาที่ไม่ได้รวมอยู่ด้วย ให้ตั้งค่าไฟล์ lunr.yourlang.js
ในโฟลเดอร์ในโปรเจ็กต์ของคุณ และเพิ่มโฟลเดอร์นั้นใน lunr_dirs
เพื่อให้ gem รู้ว่าจะต้องค้นหาจากที่ไหน
คุณสามารถปรับแต่งเนื้อหาที่จะจัดทำดัชนีและจัดเก็บต่อทรัพยากรได้อย่างเต็มที่โดยกำหนดการเรียกกลับ before_index
:
activate :search do | search |
search . before_index = Proc . new do | to_index , to_store , resource |
if author = resource . data . author
to_index [ :author ] = data . authors [ author ] . name
end
end
end
ตัวเลือกนี้ยอมรับการเรียกกลับที่จะดำเนินการสำหรับแต่ละทรัพยากร และจะดำเนินการกับเอกสารที่จะทำดัชนีและแผนที่ที่จะจัดเก็บไว้ในออบ index
และ docs
ของเอาต์พุตตามลำดับ (ดูด้านล่าง) เช่นเดียวกับทรัพยากร กำลังดำเนินการ คุณสามารถใช้การโทรกลับนี้เพื่อแก้ไขอย่างใดอย่างหนึ่ง หรือ throw(:skip)
เพื่อข้ามทรัพยากรที่ต้องการ
ในบางกรณี คุณอาจต้องการเพิ่มฟังก์ชันใหม่ให้กับไปป์ไลน์ lunr ทั้งสำหรับการสร้างดัชนีและสำหรับการค้นหา คุณสามารถทำได้โดยระบุ pipeline
แฮชพร้อมชื่อฟังก์ชันและเนื้อหา เช่น:
activate :search do | search |
search . pipeline = {
tildes : <<-JS
function(token, tokenIndex, tokens) {
return token
.replace('á', 'a')
.replace('é', 'e')
.replace('í', 'i')
.replace('ó', 'o')
.replace('ú', 'u');
}
JS
}
end
สิ่งนี้จะลงทะเบียนฟังก์ชัน tildes
ในไปป์ไลน์ lunr และเพิ่มเมื่อสร้างดัชนี จากเอกสารของ Lunr :
ฟังก์ชันในไปป์ไลน์ถูกเรียกด้วยอาร์กิวเมนต์สามตัว: โทเค็นปัจจุบันกำลังประมวลผล; ดัชนีของโทเค็นนั้นในอาร์เรย์ของโทเค็น และรายการโทเค็นทั้งหมดส่วนหนึ่งของเอกสารที่กำลังประมวลผล สิ่งนี้ทำให้การประมวลผลโทเค็นแบบยูนิแกรมอย่างง่ายรวมถึงการประมวลผล n-gram ที่ซับซ้อนยิ่งขึ้น
ฟังก์ชันควรส่งคืนข้อความเวอร์ชันที่ประมวลผลแล้ว ซึ่งจะถูกส่งไปยังฟังก์ชันถัดไปในไปป์ไลน์ การส่งคืนที่ไม่ได้กำหนดจะป้องกันการประมวลผลโทเค็นเพิ่มเติม และโทเค็นนั้นจะไม่ส่งไปยังดัชนี
โปรดทราบว่าหากคุณเพิ่มฟังก์ชันลงในไปป์ไลน์ ฟังก์ชันนั้นจะถูกโหลดเมื่อยกเลิกการซีเรียลไลซ์ดัชนี และ lunr จะล้มเหลวด้วย Cannot load un-registered function: tildes
error if it has not been re-register. คุณสามารถลงทะเบียนด้วยตนเอง หรือเพียงรวมสิ่งต่อไปนี้ในไฟล์ .js.erb
ที่จะดำเนินการ ก่อนที่ จะโหลดดัชนี:
<%= search_lunr_js_pipeline %>
ไฟล์ดัชนีที่สร้างขึ้นมีออบเจ็กต์ JSON ที่มีคุณสมบัติสองประการ:
index
ประกอบด้วยดัชนี lunr.js ที่ต่อเนื่องกัน ซึ่งคุณสามารถโหลดผ่าน lunr.Index.load(lunrData.index)
docs
คือการแมปจากรหัสเอกสารที่สร้างขึ้นอัตโนมัติไปยังออบเจ็กต์ที่มีคุณลักษณะที่กำหนดค่าไว้สำหรับการจัดเก็บ โดยทั่วไปคุณจะโหลด index
ลงในอินสแตนซ์ดัชนี lunr จากนั้นใช้แผนผัง docs
เพื่อค้นหาค่าที่ส่งคืนและนำเสนอต่อผู้ใช้
คุณควร require
ไฟล์ lunr.min.js
ในไฟล์จาวาสคริปต์ sprockets หลักของคุณ (หากใช้ไปป์ไลน์สินทรัพย์) เพื่อให้สามารถโหลดดัชนีได้จริง:
//= require lunr.min
หากคุณใช้ความสามารถ i18n ของ lunr คุณควรโหลดการสนับสนุน Stemmer และไฟล์ภาษา (ตามลำดับ) ที่นี่:
//= require lunr.min
//= require lunr.stemmer.support
//= require lunr.es
ไปป์ไลน์คนกลาง (หากเปิดใช้งาน) จะไม่รวมไฟล์ json
ตามค่าเริ่มต้น แต่คุณสามารถแก้ไขได้ง่ายๆ โดยการเพิ่ม .json
ให้กับตัวเลือก exts
ของส่วนขยายที่เกี่ยวข้อง เช่น gzip
และ asset_hash
:
activate :asset_hash do | asset_hash |
asset_hash . exts << '.json'
end
โปรดทราบว่าหากคุณเรียกใช้ไฟล์ดัชนี json ผ่านส่วนขยายแฮชเนื้อหา คุณจะต้องดึงข้อมูล URL ปลายทางจริงเมื่อโหลดไฟล์ในเบราว์เซอร์เพื่อทำการค้นหา โดยใช้ตัวช่วยดู search_index_path
:
var lunrIndex = null ;
var lunrData = null ;
// Download index data
$ . ajax ( {
url : "<%= search_index_path %>" ,
cache : true ,
method : 'GET' ,
success : function ( data ) {
lunrData = data ;
lunrIndex = lunr . Index . load ( lunrData . index ) ;
}
} ) ;
ขอบคุณมากสำหรับ:
middleman-alias
ของเขา ซึ่งเราใช้ในการพัฒนาส่วนขยายนี้middleman-lunrjs
และ middleman-lunr
ซึ่งทำหน้าที่เป็นแรงบันดาลใจในการสร้างส่วนขยายนี้lunr.js
ทั้งหมด