অ্যান্ড্রয়েডে সম্পূর্ণ পাঠ্য অনুসন্ধানের উদাহরণ


89

অ্যান্ড্রয়েডের সাথে কীভাবে সম্পূর্ণ পাঠ্য অনুসন্ধান (এফটিএস) ব্যবহার করবেন তা বুঝতে আমার খুব কষ্ট হচ্ছে। আমি FTS3 এবং FTS4 এক্সটেনশনে SQLite ডকুমেন্টেশন পড়েছি । এবং আমি জানি অ্যান্ড্রয়েডে এটি করা সম্ভব । যাইহোক, আমি বুঝতে পারছি এমন কোনও উদাহরণ খুঁজে পেতে আমার খুব কষ্ট হচ্ছে।

বেসিক ডাটাবেস মডেল

একটি এসকিউএল ডাটাবেস টেবিলের (নামযুক্ত example_table) 4 টি কলাম রয়েছে। তবে, একটি মাত্র কলাম (নামযুক্ত text_column) রয়েছে যা সম্পূর্ণ পাঠ্য অনুসন্ধানের জন্য সূচী করা দরকার। প্রতিটি সারিতে text_column0 থেকে 1000 শব্দের দৈর্ঘ্যের পাঠ্য থাকে। মোট সারির সংখ্যা 10,000 টিরও বেশি।

  • আপনি কীভাবে সারণী এবং / অথবা এফটিএস ভার্চুয়াল টেবিল সেট আপ করবেন?
  • আপনি কিভাবে এফটিএস কোয়েরি সম্পাদন করবেন text_column?

অতিরিক্ত নোট:

  • যেহেতু কেবল একটি কলামই সূচী করা দরকার, কেবল একটি FTS টেবিল ব্যবহার করা (এবং ড্রপিং example_table) অ-এফটিএস প্রশ্নের জন্য অকার্যকর হবে ।
  • এত বড় টেবিলের জন্য, text_columnএফটিএস টেবিলের নকল প্রবেশগুলি সংরক্ষণ করা অনাকাঙ্ক্ষিত হবে be এই পোস্টটি একটি বাহ্যিক সামগ্রী সারণী ব্যবহার করার পরামর্শ দেয় ।
  • বাহ্যিক সামগ্রীর টেবিলগুলি FTS4 ব্যবহার করে তবে এন্ড্রয়েড এপিআই 11 এর আগে এফটিএস 4 সমর্থিত নয় । একটি উত্তর একটি এআইপিআই> = 11 ধরে নিতে পারে তবে কম সংস্করণকে সমর্থন করার জন্য বিকল্পগুলির বিষয়ে মন্তব্য করা সহায়ক হবে।
  • মূল সারণীতে ডেটা পরিবর্তন করা এফটিএস টেবিলটি স্বয়ংক্রিয়ভাবে আপডেট করে না (এবং বিপরীতে)। আপনার উত্তরে ট্রিগারগুলি অন্তর্ভুক্ত করা এই প্রাথমিক উদাহরণের জন্য প্রয়োজনীয় নয় তবে তা তবে সহায়ক হবে।

4
ভাল-নথিভুক্ত প্রশ্ন, আমি এখানে পেয়েছি স্বেচ্ছাচারী ডাউনভোটের সাথে লড়াই করছি।
মেকাপ

উত্তর:


118

সর্বাধিক বেসিক উত্তর

আমি নীচে সরল স্ক্যুএল ব্যবহার করছি যাতে সবকিছু যথাসম্ভব স্পষ্ট এবং পঠনযোগ্য। আপনার প্রকল্পে আপনি অ্যান্ড্রয়েড সুবিধার পদ্ধতিগুলি ব্যবহার করতে পারেন। dbনিচে ব্যবহৃত বস্তুর একটি দৃষ্টান্ত হল SQLiteDatabase

এফটিএস সারণী তৈরি করুন

db.execSQL("CREATE VIRTUAL TABLE fts_table USING fts3 ( col_1, col_2, text_column )");

এটি onCreate()আপনার বর্ধিত SQLiteOpenHelperশ্রেণীর পদ্ধতিতে যেতে পারে ।

জনগণের এফটিএস সারণী

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.')");

এসকিউএলডিড ডাটাবেস # টি sertোকানো বা এর চেয়ে প্রস্তুত বিবৃতি ব্যবহার করা ভাল execSQL

এফটিএস সারণী অনুসন্ধান

String[] selectionArgs = { searchString };
Cursor cursor = db.rawQuery("SELECT * FROM fts_table WHERE fts_table MATCH ?", selectionArgs);

আপনি এসকিউএলডিটাবেস # কোয়েরি পদ্ধতিটিও ব্যবহার করতে পারেন । MATCHকীওয়ার্ডটি নোট করুন ।

পূর্ণ উত্তর

উপরের ভার্চুয়াল এফটিএস টেবিলটিতে এটি সমস্যা রয়েছে। প্রতিটি কলাম ইনডেক্স করা হয়, তবে এটি যদি কিছু কলামকে সূচীকরণের প্রয়োজন না হয় তবে স্থান এবং সংস্থানগুলির অপচয় waste এফটিএস সূচকের প্রয়োজন একমাত্র কলামটি সম্ভবত এটি text_column

এই সমস্যাটি সমাধান করার জন্য আমরা একটি নিয়মিত টেবিল এবং ভার্চুয়াল এফটিএস টেবিলের সংমিশ্রণটি ব্যবহার করব। এফটিএস সারণিতে সূচি থাকবে তবে নিয়মিত সারণী থেকে আসল তথ্যগুলির মধ্যে একটিও নেই। পরিবর্তে এটিতে নিয়মিত সারণীর সামগ্রীর লিঙ্ক থাকবে। এটিকে বাহ্যিক সামগ্রী সারণী বলা হয় ।

এখানে চিত্র বর্ণনা লিখুন

টেবিলগুলি তৈরি করুন

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)");

লক্ষ্য করুন যে এফটিএস 3 এর চেয়ে আমাদের এটি করতে FTS4 ব্যবহার করতে হবে। এপিআই সংস্করণ ১১ এর আগে অ্যান্ড্রয়েডে এফটিএস 4 সমর্থিত নয় আপনি হয় (1) কেবলমাত্র API> = 11 এর জন্য অনুসন্ধান কার্যকারিতা সরবরাহ করতে পারেন বা (2) একটি FTS3 টেবিল ব্যবহার করতে পারেন (তবে এর অর্থ ডাটাবেস আরও বড় হবে কারণ পুরো পাঠ্য কলামটি বিদ্যমান উভয় ডাটাবেসে)।

টেবিলগুলি বসান

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.')");

(আবার, সন্নিবেশ করার আরও ভাল উপায় রয়েছে এর চেয়ে ভাল execSQLI

আপনি যদি এখনই কোনও এফটিএস কোয়েরি করার চেষ্টা করে থাকেন fts_example_tableতবে কোনও ফল পাবেন না। কারণটি হ'ল একটি টেবিল পরিবর্তন করা অন্য টেবিলে স্বয়ংক্রিয়ভাবে পরিবর্তন হয় না। আপনাকে ম্যানুয়ালি এফটিএস টেবিল আপডেট করতে হবে:

db.execSQL("INSERT INTO fts_example_table (docid, text_column) SELECT _id, text_column FROM example_table");

( docidএটি rowidএকটি নিয়মিত টেবিলের মতো। এটি জটিল হয়ে উঠতে পারে। আপনি যদি কেবল একটি প্রাক-উত্পাদিত ডাটাবেস তৈরি করেন তবে আপনি এটি করতে পারেন

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);

আরও পড়া

এফটিএস ভার্চুয়াল টেবিলগুলি ব্যবহারের অন্যান্য উপায়গুলি সাবধানে এই নথিগুলির মধ্য দিয়ে যান:

অতিরিক্ত নোট


4
প্রকৃতপক্ষে, আপনি যদি সুনির্দিষ্টভাবে fts টেবিলটি ব্যবহার করেন (নন-এফটিএস টেবিল থেকে বাছাই করা যেখানে _id থাকে ডক্সিডের সেটটিতে fts টেবিলের ম্যাচ দিয়ে ফিরে আসে), আপনি বিষয়বস্তু ব্যবহার করে স্থান বাঁচাতে পারবেন = "" । এটি সামগ্রীর নকল ছাড়াই পূর্ণ-পাঠ্য সূচি তৈরি করবে। দেখুন Contentless FTS4 টেবিল
astyanaxas

এফটিএস 4 বিষয়বস্তু বিকল্পটি এসকিউএলটি 3.7.9 ( sqlite.org/releaselog/3_7_11.html ) এর চেয়ে বেশি আগে যুক্ত করা হয়নি , যার অর্থ এটি অ্যান্ড্রয়েড এপিআই 16 এর আগে অনুপলব্ধ .. এসকিউএলডিটি ডাটাবেস ব্যবহারের প্রচেষ্টা চালিয়ে যাবে।
নাকলস

এই কোয়েরির মাধ্যমে আমি কীভাবে অর্ধেক শব্দটির মিল পাব?
হিতেশ দানিধারিয়া

@ হিটেশ দানীধারিয়া, এটি কি আংশিক শব্দের সাথে মেলে না? দুঃখিত, আমি এটি নিয়ে কাজ করার পরে অনেক সময় হয়ে গেছে তবে আমি ভেবেছিলাম এটি এটি ইতিমধ্যে হয়ে গেছে।
সুরগাচ

@ সুরগাচ সমাধান পেয়ে গেলেন the সার্চস্ট্রিংয়ের পরে "*" যুক্ত করার জন্য ধন্যবাদ এবং ধন্যবাদ Y আপনার উত্তরটি আমাকে অনেক সাহায্য করেছে। :)
হিতেশ দানিধারিয়া

3

Fts টেবিলটি পুনর্নির্মাণ করতে কন্টেন্ট ব্যবহার করার সময় ভুলে যাবেন না।

আমি আপডেট, সন্নিবেশ, মুছার উপর একটি ট্রিগার দিয়ে এটি করি


INSERT INTO foo_fts VALUES("rebuild")
জেমস কিপলিং
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.