ไลบรารีการจัดทำดัชนีข้อความเต็มรูปแบบที่รวดเร็วและน้อยที่สุดซึ่งเขียนใน Objective-C สร้างขึ้นบน Objective-LevelDB
จนถึงตอนนี้วิธีที่ง่ายที่สุดในการรวมห้องสมุดนี้ในโครงการของคุณคือการใช้ cocoapods
ติดตั้ง cocoapods ถ้าคุณยังไม่ได้อยู่แล้ว
ใน podfile ของคุณเพิ่มบรรทัด
pod 'MHTextSearch'
Run pod install
เพิ่ม libc++.dylib Framework ลงในโครงการของคุณ
MHTextIndex *index = [MHTextIndex textIndexInLibraryWithName: @" my.awesome.index " ]; คุณสามารถบอกอินสแตนซ์ MHTextIndex เพื่อจัดทำดัชนีวัตถุของคุณ (วัตถุใด ๆ )
[ index indexObject: anyObjectYouWant];
[ index updateIndexForObject: anotherPreviousIndexedObject];
[ index removeIndexForObject: anotherPreviousIndexedObject]; แต่สำหรับการทำงานนี้คุณต้องบอกเราว่า ตัวระบุ ว่า NSData * สามารถใช้เพื่ออ้างถึงวัตถุนี้ได้โดยเฉพาะ
[ index setIdentifier: ^ NSData *(MyCustomObject *object){
return object. indexID ; // a NSData instance
}];คุณต้องให้รายละเอียดเกี่ยวกับวัตถุเช่นเดียวกับสิ่งที่เป็นชิ้นส่วนของข้อความที่จะทำดัชนี
[ index setIndexer: ^MHIndexedObject *(MyCustomObject *object, NSData *identifier){
MHIndexedObject *indx = [MHIndexedObject new ];
indx. strings = @[ object.title, object.description ]; // Indexed strings
indx. weight = object. awesomenessLevel ; // Weight given to this object, when sorting results
indx. context = @{ @" title " : object. title }; // A NSDictionary that will be given alongside search results
return indx;
}];สุดท้ายหากคุณต้องการให้สามารถอ้างอิงวัตถุต้นฉบับของคุณได้อย่างง่ายดายเมื่อคุณได้รับผลการค้นหาคุณสามารถบอกเราว่าจะทำอย่างไรให้คุณ
[ index setObjectGetter: ^MyCustomObject *( NSData *identifier){
return [MyCustomObject customObjectFromIdentifier: identifier];
}];แล้ว ก็แค่ไหน! นั่นคือทั้งหมดที่คุณต้องได้รับดัชนีข้อความเต็ม MHTextSearch ดูแลการแยกข้อความออกเป็นคำพูดออกมา diacritics และการใช้อักษรตัวพิมพ์ใหญ่ทั้งหมดที่เกี่ยวกับสถานที่ตามที่คุณคาดหวัง (ดีมูลนิธิทำงานส่วนใหญ่ของที่นี่)
จากนั้นคุณสามารถเริ่มค้นหา:
[ index enumerateObjectsForKeyword: @" duck " options: 0 withBlock: ^(MHSearchResultItem *item,
NSUInteger rank,
NSUInteger count,
BOOL *stop){
item. weight ; // As provided by you earlier
item. rank ; // The effective rank in the search result
item. object ; // The first time it is used, it will use the block
// you provided earlier to get the object
item. context ; // The dictionary you provided in the "indexer" block
item. identifier ; // The object identifier you provided in the "identifier" block
NSIndexPath *token = item. resultTokens [ 0 ];
/* This is an NSArray of NSIndexPath instances, each containing 3 indices:
* - mh_string : the string in which the token occured
* (here, 0 for the object's title)
* - mh_word : the position in the string where the word containing
* the token occured
* - mh_token : the position in the word where the token occured
*/
NSRange tokenRange = [item rangeOfToken: token];
/* This gives the exact range of the matched token in the string where it was found.
*
* So, according to the example setup I've been giving from the start,
* if token.mh_string == 0, that means the token was found in the object's "title",
* and [item.object.title substringWithRange:tokenRange] would yield "duck" (minus
* capitalization and diacritics).
*/
}]; นอกจากนี้คุณยังสามารถดึงอินสแตนซ์ MHSearchResultItem ทั้งหมดได้ในครั้งเดียว
NSArray *resultSet = [ index searchResultForKeyword: @" duck "
options: NSEnumerationReverse];หากการให้บล็อกสำหรับการระบุพฤติกรรมไม่ใช่สิ่งที่คุณต้องการคุณสามารถแทนที่วิธีการต่อไปนี้:
-[MHTextIndex getIdentifierForObject:] ซึ่งโดยค่าเริ่มต้นใช้บล็อก identifier-[MHTextIndex getIndexInfoForObject:andIdentifier:] ซึ่งโดยค่าเริ่มต้นจะใช้บล็อก indexer-[MHTextIndex compareResultItem:withItem:reversed:] ซึ่งใช้ในการสั่งซื้อชุดผลการค้นหา คุณสามารถใช้วิธีวงจรชีวิตของ NSManagedObject เพื่อกระตุ้นการเปลี่ยนแปลงดัชนีข้อความ ตัวอย่างต่อไปนี้ถูกนำมาจาก http://www.adevelopingstory.com/blog/2013/04/adding-full-text-search-to-core-data.html และปรับให้ใช้กับโครงการนี้:
- ( void )prepareForDeletion
{
[ super prepareForDeletion ];
if (self. indexID . length ) {
[textindex deleteIndexForObject: self .indexID];
}
}
+ ( NSData *)createIndexID {
NSUUID *uuid = [ NSUUID UUID ];
uuid_t uuidBytes;
[uuid getUUIDBytes: uuidBytes];
return [ NSData dataWithBytes: uuidBytes length: 16 ];
}
- ( void )willSave
{
[ super willSave ];
if (self. indexID . length ) {
[textindex updateIndexForObject: self .indexID];
} else {
self. indexID = [[ self class ] createIndexID ];
[textindex indexObject: self .indexID];
}
} MHTextIndex ใช้ NSOperationQueue ภายใต้ฮูดเพื่อประสานงานการจัดทำดัชนี มันถูกเปิดเผยว่าเป็นคุณสมบัติที่มีชื่อว่า indexingQueue คุณสามารถตั้งค่าคุณสมบัติ maxConcurrentOperationCount เพื่อควบคุมว่าการทำดัชนีพร้อมกันสามารถเกิดขึ้นได้อย่างไร เนื่องจากไลบรารีฐานข้อมูลพื้นฐานที่ดำเนินการ I/O เป็นเธรดที่ปลอดภัยการเกิดขึ้นพร้อมกันจึงไม่ใช่ปัญหา นี่ก็หมายความว่าคุณสามารถรอการจัดทำดัชนีการดำเนินการอย่างชัดเจนโดยใช้:
[ index .indexingQueue waitUntilAllOperationsAreFinished ]; วิธีการจัดทำดัชนีสามวิธี -[MHTextIndex indexObject:] , -[MHTextIndex updateIndexForObject:] , -[MHTextIndex ลบ -[NSOperation waitUntilFinished] -[MHTextIndex removeIndexForObject:] ทั้งหมดส่งคืนอิน completionBlock ซ์ NSOperation ที่คุณสามารถใช้ประโยชน์ได้หากคุณต้องการ
การค้นหาก็เกิดขึ้นพร้อมกัน แต่ก็ใช้ dispatch_queue_t (ยังไม่ได้สัมผัสหรือปรับได้)
มีลูกบิดสองสามตัวที่คุณสามารถเล่นด้วยเพื่อให้ MHTextSeach เหมาะกับความต้องการของคุณดีขึ้น
อินสแตนซ์ MHTextIndex มีคุณสมบัติบูลีน skipStopWords ที่เป็นจริงโดยค่าเริ่มต้นและหลีกเลี่ยงการจัดทำดัชนีคำภาษาอังกฤษที่พบบ่อยมาก ( สิ่งที่ต้องทำ : ทำให้การทำงานกับภาษาอื่น ๆ )
นอกจากนี้ยังมีความ minimalTokenLength ที่เท่ากับ 2 โดยค่าเริ่มต้น สิ่งนี้ตั้งค่าขั้นต่ำสำหรับจำนวนตัวอักษรที่โทเค็นจำเป็นต้องได้รับการจัดทำดัชนี นอกจากนี้ยังช่วยลดขนาดของดัชนีได้อย่างมากเช่นเดียวกับเวลาในการทำดัชนีและการค้นหา มันข้ามการจัดทำดัชนีคำเดียวตัวอักษรและตัวอักษรสุดท้ายของทุกคำเมื่อตั้งค่าเป็น 2
เมื่อจัดทำดัชนีข้อความแบบฟอร์มยาว (เอกสารแทนที่จะพูดชื่อง่าย ๆ ) คุณสามารถเปิดคุณสมบัติบูลีน discardDuplicateTokens บน MHTextIndex สิ่งนี้ทำให้ดัชนีพิจารณาการเกิดขึ้นครั้งแรกของโทเค็นที่จัดทำดัชนีทุกรายการสำหรับข้อความที่กำหนด หากคุณโอเคเพียงแค่รู้ ว่า โทเค็นปรากฏในข้อความแทนที่จะปรากฏ ขึ้น ทุกครั้งที่ปรากฏขึ้นคุณสามารถได้รับความเร็วในการ จัดทำดัชนี โดยปัจจัย 3 ถึง 5
กราฟต่อไปนี้แสดงการจัดทำดัชนีและเวลาการค้นหา (เป็นวินาที) เป็นฟังก์ชั่นขนาดของข้อความที่จัดทำดัชนีตั้งแต่ 500 kb ถึงประมาณ 10 MB เกณฑ์มาตรฐานทำงานบน iPhone 5
หากคุณต้องการเรียกใช้การทดสอบคุณจะต้องมี XCode 5 เนื่องจากชุดทดสอบใช้ XCTEST ใหม่
โคลนที่เก็บนี้และครั้งหนึ่งในนั้น
$ cd MHTextSearch iOS Tests
$ pod install
$ cd .. && open * .xcworkspaceปัจจุบันการทดสอบทั้งหมดได้รับการตั้งค่าให้ทำงานกับชุดทดสอบ iOS
แจกจ่ายภายใต้ใบอนุญาต MIT