सबसे बुनियादी जवाब
मैं नीचे दिए गए सादे वर्ग का उपयोग कर रहा हूं ताकि सब कुछ यथासंभव स्पष्ट और पठनीय हो। अपने प्रोजेक्ट में आप Android सुविधा विधियों का उपयोग कर सकते हैं। db
नीचे इस्तेमाल किया वस्तु का एक उदाहरण है SQLiteDatabase ।
एफटीएस टेबल बनाएं
db.execSQL("CREATE VIRTUAL TABLE fts_table USING fts3 ( col_1, col_2, text_column )");
यह onCreate()
आपके विस्तारित SQLiteOpenHelper
वर्ग की विधि में जा सकता है ।
FTS टेबल पॉप्युलेट करें
db.execSQL("INSERT INTO fts_table VALUES ('3', 'apple', 'Hello. How are you?')");
db.execSQL("INSERT INTO fts_table VALUES ('24', 'car', 'Fine. Thank you.')");
db.execSQL("INSERT INTO fts_table VALUES ('13', 'book', 'This is an example.')");
यह उपयोग करने के लिए बेहतर होगा SQLiteDatabase # डालने या तैयार बयानों से execSQL
।
क्वेरी FTS तालिका
String[] selectionArgs = { searchString };
Cursor cursor = db.rawQuery("SELECT * FROM fts_table WHERE fts_table MATCH ?", selectionArgs);
आप SQLiteDatabase # query विधि का उपयोग भी कर सकते हैं । MATCH
कीवर्ड नोट करें ।
फुलर उत्तर
वर्चुअल FTS टेबल के साथ एक समस्या है। प्रत्येक कॉलम को अनुक्रमित किया जाता है, लेकिन यह स्थान और संसाधनों की बर्बादी है अगर कुछ कॉलमों को अनुक्रमित करने की आवश्यकता नहीं है। एकमात्र स्तंभ जिसे एफटीएस इंडेक्स की आवश्यकता होती है वह शायद है text_column
।
इस समस्या को हल करने के लिए हम एक नियमित तालिका और एक आभासी FTS तालिका के संयोजन का उपयोग करेंगे। एफटीएस तालिका में सूचकांक शामिल होगा लेकिन नियमित तालिका से कोई भी वास्तविक डेटा नहीं होगा। इसके बजाय इसमें रेगुलर टेबल के कंटेंट का लिंक होगा। इसे बाहरी सामग्री तालिका कहा जाता है ।
टेबल्स बनाएँ
db.execSQL("CREATE TABLE example_table (_id INTEGER PRIMARY KEY, col_1 INTEGER, col_2 TEXT, text_column TEXT)");
db.execSQL("CREATE VIRTUAL TABLE fts_example_table USING fts4 (content='example_table', text_column)");
ध्यान दें कि हमें FTS3 के बजाय ऐसा करने के लिए FTS4 का उपयोग करना होगा। एफटीएस 4 को एपीआई संस्करण 11 से पहले एंड्रॉइड में समर्थित नहीं है। आप या तो (1) केवल एपीआई> = 11 के लिए खोज कार्यक्षमता प्रदान कर सकते हैं, या (2) एफटीएस 3 तालिका का उपयोग कर सकते हैं (लेकिन इसका मतलब है कि डेटाबेस बड़ा होगा क्योंकि पूर्ण पाठ कॉलम मौजूद है दोनों डेटाबेस में)।
तालिकाओं को आबाद करें
db.execSQL("INSERT INTO example_table (col_1, col_2, text_column) VALUES ('3', 'apple', 'Hello. How are you?')");
db.execSQL("INSERT INTO example_table (col_1, col_2, text_column) VALUES ('24', 'car', 'Fine. Thank you.')");
db.execSQL("INSERT INTO example_table (col_1, col_2, text_column) VALUES ('13', 'book', 'This is an example.')");
(फिर, वहाँ बेहतर तरीके से आवेषण के साथ की तुलना में कर रहे हैं execSQL
। मैं सिर्फ अपनी पठनीयता के लिए उपयोग कर रहा हूँ।)
यदि आपने FTS क्वेरी करने की कोशिश की तो अब fts_example_table
आपको कोई परिणाम नहीं मिलेगा। कारण यह है कि एक तालिका को बदलने से स्वचालित रूप से दूसरी तालिका नहीं बदल जाती है। आपको एफटीएस तालिका को मैन्युअल रूप से अपडेट करना होगा:
db.execSQL("INSERT INTO fts_example_table (docid, text_column) SELECT _id, text_column FROM example_table");
( एक रेगुलर टेबल docid
के rowid
लिए जैसा है ।) आपको हर बार एफटीएस टेबल (ताकि यह इंडेक्स को अपडेट कर सके) को बाहरी सामग्री तालिका में बदलाव (INSERT, DELETE, UPDATE) से अपडेट करना सुनिश्चित करना होगा। इससे बोझिल हो सकते हैं। यदि आप केवल एक पूर्वनिर्मित डेटाबेस बना रहे हैं, तो आप कर सकते हैं
db.execSQL("INSERT INTO fts_example_table(fts_example_table) VALUES('rebuild')");
जो पूरी तालिका का पुनर्निर्माण करेगा। यह धीमा हो सकता है, हालांकि, इसलिए यह ऐसा कुछ नहीं है जिसे आप हर छोटे बदलाव के बाद करना चाहते हैं। आप बाहरी सामग्री तालिका पर सभी आवेषण समाप्त करने के बाद इसे करेंगे। यदि आपको डेटाबेस को स्वचालित रूप से सिंक करने की आवश्यकता है, तो आप ट्रिगर्स का उपयोग कर सकते हैं । यहां जाएं और दिशाओं को खोजने के लिए थोड़ा नीचे स्क्रॉल करें।
डेटाबेस को क्वेरी करें
String[] selectionArgs = { searchString };
Cursor cursor = db.rawQuery("SELECT * FROM fts_example_table WHERE fts_example_table MATCH ?", selectionArgs);
यह पहले की तरह ही है, इस समय को छोड़कर आपके पास केवल text_column
(और docid
) की पहुंच है । क्या होगा यदि आपको बाहरी सामग्री तालिका में अन्य स्तंभों से डेटा प्राप्त करने की आवश्यकता है? चूंकि docid
एफटीएस तालिका बाहरी सामग्री तालिका के rowid
(और इस मामले में _id
) से मेल खाती है , तो आप एक जॉइन का उपयोग कर सकते हैं। ( उस के लिए मदद के लिए इस जवाब के लिए धन्यवाद ।)
String sql = "SELECT * FROM example_table WHERE _id IN " +
"(SELECT docid FROM fts_example_table WHERE fts_example_table MATCH ?)";
String[] selectionArgs = { searchString };
Cursor cursor = db.rawQuery(sql, selectionArgs);
आगे की पढाई
FTS वर्चुअल टेबल का उपयोग करने के अन्य तरीकों को देखने के लिए इन दस्तावेजों को ध्यान से देखें:
अतिरिक्त नोट्स