Perpustakaan pengindeksan teks lengkap yang cepat & minimal, ditulis dalam Objective-C, dibangun di atas leveldb objektif.
Sejauh ini, cara termudah untuk mengintegrasikan perpustakaan ini dalam proyek Anda adalah dengan menggunakan cocoapods.
Telah menginstal cocoapods, jika Anda belum melakukannya
Di podfile Anda, tambahkan garis
pod 'MHTextSearch'
Jalankan pod install
Tambahkan libc++.dylib Framework ke proyek Anda.
MHTextIndex *index = [MHTextIndex textIndexInLibraryWithName: @" my.awesome.index " ]; Anda dapat memberi tahu contoh MHTextIndex untuk mengindeks objek Anda (objek apa pun)
[ index indexObject: anyObjectYouWant];
[ index updateIndexForObject: anotherPreviousIndexedObject];
[ index removeIndexForObject: anotherPreviousIndexedObject]; Tetapi agar ini berfungsi, Anda perlu memberi tahu kami pengidentifikasi apa NSData * dapat digunakan untuk secara unik merujuk pada objek ini.
[ index setIdentifier: ^ NSData *(MyCustomObject *object){
return object. indexID ; // a NSData instance
}];Anda juga perlu memberi kami detail tentang objek, seperti apa bagian teks untuk diindeks
[ 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;
}];Akhirnya, jika Anda ingin bisa mendapatkan referensi yang mudah ke objek asli Anda saat Anda mendapatkan hasil pencarian, Anda dapat memberi tahu kami cara melakukannya untuk Anda
[ index setObjectGetter: ^MyCustomObject *( NSData *identifier){
return [MyCustomObject customObjectFromIdentifier: identifier];
}];Dan itu saja! Hanya itu yang Anda butuhkan untuk mendapatkan indeks teks lengkap. MHTextSearch menangani pemisahan teks menjadi kata -kata, memperhitungkan diakritik dan kapitalisasi, semuanya sehubungan dengan lokal, seperti yang Anda harapkan (yayasan, fondasi melakukan sebagian besar pekerjaan di sini).
Anda kemudian dapat mulai mencari:
[ 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).
*/
}]; Anda juga dapat mengambil seluruh array instance MHSearchResultItem sekaligus menggunakan
NSArray *resultSet = [ index searchResultForKeyword: @" duck "
options: NSEnumerationReverse];Jika memberi blok untuk menentukan perilaku bukan urusan Anda, Anda juga dapat mengganti metode berikut:
-[MHTextIndex getIdentifierForObject:] yang, secara default menggunakan blok identifier-[MHTextIndex getIndexInfoForObject:andIdentifier:] Yang, secara default menggunakan blok indexer-[MHTextIndex compareResultItem:withItem:reversed:] yang digunakan untuk memesan set hasil pencarian Anda dapat menggunakan metode siklus hidup NSManagedObject untuk memicu perubahan pada indeks teks. Contoh berikut diambil dari http://www.adevelevelystory.com/blog/2013/04/adding-full-text-search-to-core-data.html dan diadaptasi untuk digunakan dengan proyek ini:
- ( 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 menggunakan NSOperationQueue di bawah kap untuk mengoordinasikan operasi pengindeksan. Ini diekspos sebagai properti bernama indexingQueue . Dengan demikian Anda dapat mengatur properti maxConcurrentOperationCount untuk mengontrol seberapa bersamaan pengindeksan. Karena pustaka database yang mendasarinya melakukan I/O adalah utas-aman, konkurensi tidak menjadi masalah. Ini juga berarti Anda dapat secara eksplisit menunggu operasi pengindeksan selesai menggunakan:
[ index .indexingQueue waitUntilAllOperationsAreFinished ]; Tiga metode pengindeksan -[MHTextIndex indexObject:] , -[MHTextIndex updateIndexForObject:] , -[MHTextIndex removeIndexForObject:] Semua mengembalikan instance NSOperation , yang dapat Anda manfaatkan, jika Anda membutuhkan, menggunakan Metode completionBlock atau -[NSOperation waitUntilFinished] .
Pencarian juga bersamaan, tetapi menggunakan dispatch_queue_t (belum diekspos atau disetel).
Ada beberapa tombol yang bisa Anda mainkan untuk membuat MHTextSeach lebih sesuai dengan kebutuhan Anda.
Contoh MHTextIndex memiliki properti Boolean skipStopWords yang benar secara default dan yang menghindari pengindeksan kata -kata bahasa Inggris yang sangat umum. ( Todo : Jadikan itu bekerja dengan bahasa lain)
Ini juga memiliki minimalTokenLength yang sama dengan 2 secara default. Ini menetapkan minimum untuk jumlah huruf yang harus diindeks oleh token untuk diindeks. Ini juga sangat meminimalkan ukuran indeks, serta waktu pengindeksan dan pencarian. Ini melewatkan pengindeksan kata-kata huruf tunggal dan huruf terakhir dari setiap kata, ketika diatur ke 2 .
Saat mengindeks teks bentuk panjang (dokumen daripada, katakanlah, nama sederhana), Anda dapat menyalakan properti Boolean discardDuplicateTokens di MHTextIndex . Ini membuat indeks hanya mempertimbangkan kejadian pertama dari setiap token yang diindeks untuk sepotong teks yang diberikan. Jika Anda baik -baik saja dengan hanya mengetahui jika token muncul dalam teks, daripada di mana setiap kejadian muncul, Anda bisa mendapatkan benturan kecepatan dalam waktu pengindeksan , dengan faktor 3 hingga 5.
Grafik berikut menunjukkan waktu pengindeksan dan pencarian (dalam detik), sebagai fungsi dari ukuran teks yang diindeks, mulai dari 500 kb hingga sekitar 10 MB. Tolok ukur dijalankan pada iPhone 5.
Jika Anda ingin menjalankan tes, Anda akan memerlukan Xcode 5, karena test suite menggunakan Xctest baru.
Klon repositori ini dan, sekali di dalamnya,
$ cd MHTextSearch iOS Tests
$ pod install
$ cd .. && open * .xcworkspaceSaat ini, semua tes diatur untuk bekerja dengan IOS Test Suite.
Didistribusikan di bawah lisensi MIT