brief: | i18n.site এখন সার্ভারহীন পূর্ণ-পাঠ্য অনুসন্ধান সমর্থন করে।

এই নিবন্ধটি IndexedDB দ্বারা নির্মিত ইনভার্টেড ইনডেক্স, প্রিফিক্স অনুসন্ধান, শব্দ বিভাজন অপ্টিমাইজেশান এবং বহু-ভাষা সমর্থন সহ বিশুদ্ধ ফ্রন্ট-এন্ড পূর্ণ-টেক্সট অনুসন্ধান প্রযুক্তির বাস্তবায়নের পরিচয় দেয়।

বিদ্যমান সমাধানগুলির সাথে তুলনা করে, i18n.site-এর বিশুদ্ধ ফ্রন্ট-এন্ড ফুল-টেক্সট অনুসন্ধান আকারে ছোট এবং দ্রুত, ছোট এবং মাঝারি আকারের ওয়েবসাইট যেমন নথি এবং ব্লগগুলির জন্য উপযুক্ত এবং অফলাইনে উপলব্ধ।


বিশুদ্ধ ফ্রন্ট-এন্ড ইনভার্টেড ফুল-টেক্সট অনুসন্ধান

ক্রম

কয়েক সপ্তাহের বিকাশের পর i18n.site (একটি সম্পূর্ণরূপে স্থির markdown বহুভাষিক অনুবাদ & ওয়েবসাইট নির্মাণ টুল) এখন বিশুদ্ধ ফ্রন্ট-এন্ড পূর্ণ-পাঠ্য অনুসন্ধান সমর্থন করে।

এই নিবন্ধটি i18n.site বিশুদ্ধ ফ্রন্ট-এন্ড ফুল-টেক্সট অনুসন্ধানের প্রযুক্তিগত বাস্তবায়ন ভাগ করবে i18n.site

কোড ওপেন : সার্চ কার্নেল / ইন্টারেক্টিভ ইন্টারফেস

সার্ভারহীন পূর্ণ-পাঠ্য অনুসন্ধান সমাধানগুলির একটি পর্যালোচনা

ছোট এবং মাঝারি আকারের সম্পূর্ণরূপে স্ট্যাটিক ওয়েবসাইট যেমন নথি/ব্যক্তিগত ব্লগের জন্য, একটি স্ব-নির্মিত পূর্ণ-পাঠ্য অনুসন্ধান ব্যাকএন্ড তৈরি করা খুব ভারী এবং পরিষেবা-মুক্ত পূর্ণ-পাঠ্য অনুসন্ধান হল আরও সাধারণ পছন্দ।

সার্ভারহীন পূর্ণ-পাঠ্য অনুসন্ধান সমাধান দুটি বিস্তৃত বিভাগে পড়ে:

প্রথমত, algolia.com তৃতীয় পক্ষের অনুসন্ধান পরিষেবা প্রদানকারীরা পূর্ণ-পাঠ্য অনুসন্ধানের জন্য ফ্রন্ট-এন্ড উপাদান সরবরাহ করে।

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

এটি অফলাইনে ব্যবহার করা যাবে না, ইন্ট্রানেটে ব্যবহার করা যাবে না এবং এর বড় সীমাবদ্ধতা রয়েছে৷ এই নিবন্ধটি খুব বেশি আলোচনা করে না।

দ্বিতীয়টি বিশুদ্ধ ফ্রন্ট-এন্ড ফুল-টেক্সট অনুসন্ধান।

বর্তমানে, সাধারণ বিশুদ্ধ ফ্রন্ট-এন্ড পূর্ণ-পাঠ্য অনুসন্ধানের মধ্যে রয়েছে lunrjs এবং ElasticLunr.js ( lunrjs সেকেন্ডারি বিকাশের উপর ভিত্তি করে)।

lunrjs সূচী তৈরি করার দুটি উপায় রয়েছে এবং উভয়েরই নিজস্ব সমস্যা রয়েছে।

  1. প্রি-বিল্ট ইনডেক্স ফাইল

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

  2. নথি লোড করুন এবং ফ্লাইতে ইনডেক্স তৈরি করুন

    একটি সূচক তৈরি করা একটি গণনামূলকভাবে নিবিড় কাজ যা আপনি যখনই এটি অ্যাক্সেস করেন তখন সূচকটি পুনর্নির্মাণ করা সুস্পষ্ট পিছিয়ে এবং দুর্বল ব্যবহারকারীর অভিজ্ঞতার কারণ হবে৷


lunrjs ছাড়াও, আরও কিছু পূর্ণ-পাঠ্য অনুসন্ধান সমাধান রয়েছে, যেমন :

fusejs অনুসন্ধানের জন্য স্ট্রিংগুলির মধ্যে মিল গণনা করুন।

এই সমাধানটির কার্যকারিতা অত্যন্ত খারাপ এবং পূর্ণ-পাঠ্য অনুসন্ধানের জন্য ব্যবহার করা যাবে না (দেখুন Fuse.js দীর্ঘ ক্যোয়ারী 10 সেকেন্ডের বেশি সময় নেয়, কীভাবে এটি অপ্টিমাইজ করবেন? )।

TinySearch অনুসন্ধান করতে ব্লুম ফিল্টার ব্যবহার করুন, উপসর্গ অনুসন্ধানের জন্য ব্যবহার করা যাবে না (উদাহরণস্বরূপ, goo লিখুন , অনুসন্ধান good , google ), এবং অনুরূপ স্বয়ংক্রিয় সমাপ্তি প্রভাব অর্জন করতে পারবেন না।

বিদ্যমান সমাধানগুলির ত্রুটিগুলির কারণে, i18n.site একটি নতুন বিশুদ্ধ ফ্রন্ট-এন্ড ফুল-টেক্সট অনুসন্ধান সমাধান তৈরি করেছে, যার নিম্নলিখিত বৈশিষ্ট্য রয়েছে :

  1. বহু-ভাষা অনুসন্ধান সমর্থন করে এবং আকারে ছোট হয় gzip প্যাকেজিংয়ের পরে অনুসন্ধান কার্নেলের আকার 6.9KB (তুলনার জন্য, lunrjs এর আকার 25KB )
  2. indexedb এর উপর ভিত্তি করে একটি উল্টানো সূচক তৈরি করুন, যা কম মেমরি নেয় এবং দ্রুত।
  3. যখন নথিগুলি যোগ/পরিবর্তিত হয়, শুধুমাত্র যোগ করা বা পরিবর্তিত নথিগুলিকে পুনরায় সূচীভুক্ত করা হয়, গণনার পরিমাণ হ্রাস করে।
  4. উপসর্গ অনুসন্ধান সমর্থন করে এবং ব্যবহারকারী টাইপ করার সময় রিয়েল টাইমে অনুসন্ধান ফলাফল প্রদর্শন করতে পারে।
  5. অফলাইনে উপলব্ধ

নীচে, i18n.site প্রযুক্তিগত বাস্তবায়ন বিবরণ বিস্তারিতভাবে চালু করা হবে।

বহুভাষিক শব্দ বিভাজন

শব্দ বিভাজন ব্রাউজারের নেটিভ শব্দ সেগমেন্টেশন Intl.Segmenter ব্যবহার করে এবং সমস্ত মূলধারার ব্রাউজার এই ইন্টারফেসটিকে সমর্থন করে।

শব্দ বিভাজন coffeescript কোড নিম্নরূপ

SEG = new Intl.Segmenter 0, granularity: "word"

seg = (txt) =>
  r = []
  for {segment} from SEG.segment(txt)
    for i from segment.split('.')
      i = i.trim()
      if i and !'| `'.includes(i) and !/\p{P}/u.test(i)
        r.push i
  r

export default seg

export segqy = (q) =>
  seg q.toLocaleLowerCase()

মধ্যে:

সূচক বিল্ডিং

5টি অবজেক্ট স্টোরেজ টেবিল তৈরি করা হয়েছিল IndexedDB সালে :

ডকুমেন্ট url এবং ভার্সন নম্বর ver এর অ্যারে পাস করুন এবং সারণি doc এ ডকুমেন্টটি বিদ্যমান কিনা তা অনুসন্ধান করুন। যদি এটি বিদ্যমান না থাকে তবে একটি উল্টানো সূচক তৈরি করুন। একই সময়ে, পাস করা হয়নি এমন নথিগুলির জন্য উল্টানো সূচকটি সরান।

এইভাবে, ইনক্রিমেন্টাল ইনডেক্সিং অর্জন করা যায় এবং গণনার পরিমাণ হ্রাস করা যায়।

ফ্রন্ট-এন্ড ইন্টারঅ্যাকশনে, প্রথমবার লোড করার সময় ল্যাগ এড়াতে ইনডেক্সের লোডিং প্রগ্রেস বারটি প্রদর্শিত হতে পারে "একক উপর ভিত্তি করে অ্যানিমেশনের সাথে অগ্রগতি বার progress + বিশুদ্ধ css বাস্তবায়ন" ইংরেজি / চীনা

IndexedDB উচ্চ সমসাময়িক লেখা

প্রকল্পটি এর অ্যাসিঙ্ক্রোনাস এনক্যাপসুলেশনের উপর ভিত্তি করে idb IndexedDB

IndexedDB রিড এবং রাইট অসিঙ্ক্রোনাস। একটি সূচী তৈরি করার সময়, সূচক তৈরি করতে নথিগুলি একযোগে লোড করা হবে।

প্রতিযোগিতামূলক লেখার কারণে আংশিক ডেটা ক্ষতি এড়াতে, আপনি নীচের coffeescript কোডটি উল্লেখ করতে পারেন এবং প্রতিযোগী লেখাগুলিকে আটকাতে পড়া এবং লেখার মধ্যে ing ক্যাশে যোগ করতে পারেন।

pusher = =>
  ing = new Map()
  (table, id, val)=>
    id_set = ing.get(id)
    if id_set
      id_set.add val
      return

    id_set = new Set([val])
    ing.set id, id_set
    pre = await table.get(id)
    li = pre?.li or []

    loop
      to_add = [...id_set]
      li.push(...to_add)
      await table.put({id,li})
      for i from to_add
        id_set.delete i
      if not id_set.size
        ing.delete id
        break
    return

rindexPush = pusher()
prefixPush = pusher()

যথার্থতা এবং প্রত্যাহার

অনুসন্ধানটি প্রথমে ব্যবহারকারীর দ্বারা প্রবেশ করা কীওয়ার্ডগুলিকে সেগমেন্ট করবে।

অনুমান করুন যে বিভাজন শব্দের পরে N শব্দ আছে ফলাফল ফেরত দেওয়ার সময়, সমস্ত কীওয়ার্ড সম্বলিত ফলাফলগুলি প্রথমে ফেরত দেওয়া হবে এবং তারপর N-1 , N-2 ,..., 1 কীওয়ার্ড সম্বলিত ফলাফল দেওয়া হবে৷

প্রদর্শিত অনুসন্ধানের ফলাফলগুলি প্রথমে প্রশ্নের সঠিকতা নিশ্চিত করে এবং পরবর্তীতে লোড হওয়া ফলাফলগুলি (আরো লোড বোতামে ক্লিক করুন) প্রত্যাহার হার নিশ্চিত করে৷

চাহিদা অনুযায়ী লোড

প্রতিক্রিয়ার গতি উন্নত করার জন্য, অনুসন্ধানটি yield জেনারেটর ব্যবহার করে অন-ডিমান্ড লোডিং বাস্তবায়ন করে এবং limit যখন ফলাফল জিজ্ঞাসা করা হয় তখন ফিরে আসে।

মনে রাখবেন যে প্রতিবার আপনি yield এর পরে আবার অনুসন্ধান করলে, আপনাকে IndexedDB এর একটি ক্যোয়ারী লেনদেন পুনরায় খুলতে হবে।

প্রিফিক্স রিয়েল-টাইম অনুসন্ধান

ব্যবহারকারী টাইপ করার সময় অনুসন্ধানের ফলাফল প্রদর্শন করার জন্য, উদাহরণস্বরূপ, যখন wor প্রবেশ করানো হয়, তখন wor এর সাথে উপসর্গযুক্ত শব্দ যেমন words এবং work প্রদর্শিত হয়।

সার্চ কার্নেল শব্দ বিভাজনের পর শেষ শব্দের জন্য prefix টেবিল ব্যবহার করবে এবং এর সাথে উপসর্গযুক্ত সমস্ত শব্দ খুঁজে বের করবে এবং ক্রমানুসারে অনুসন্ধান করবে।

অ্যান্টি-শেক ফাংশন debounce ফ্রন্ট-এন্ড ইন্টারঅ্যাকশনেও ব্যবহার করা হয় (নিম্নলিখিতভাবে বাস্তবায়িত) ব্যবহারকারীর ইনপুট ট্রিগারিং অনুসন্ধানের ফ্রিকোয়েন্সি কমাতে এবং গণনার পরিমাণ কমাতে।

export default (wait, func) => {
  var timeout;
  return function(...args) {
    clearTimeout(timeout);
    timeout = setTimeout(func.bind(this, ...args), wait);
  };
}

অফলাইনে উপলব্ধ

সূচী সারণী মূল পাঠ্য সংরক্ষণ করে না, শুধুমাত্র শব্দ, যা সঞ্চয়ের পরিমাণ হ্রাস করে।

অনুসন্ধান ফলাফল হাইলাইট করার জন্য মূল পাঠ্য পুনরায় লোড করা প্রয়োজন, এবং service worker মেলে বারবার নেটওয়ার্ক অনুরোধগুলি এড়াতে পারে।

একই সময়ে, যেহেতু service worker সমস্ত নিবন্ধ ক্যাশ করে, ব্যবহারকারী একবার অনুসন্ধান করে, অনুসন্ধান সহ সমগ্র ওয়েবসাইট অফলাইনে উপলব্ধ।

মার্কডাউন নথির অপ্টিমাইজেশন প্রদর্শন করুন

i18n.site এর বিশুদ্ধ ফ্রন্ট-এন্ড অনুসন্ধান সমাধান MarkDown নথির জন্য অপ্টিমাইজ করা হয়েছে।

অনুসন্ধান ফলাফল প্রদর্শন করার সময়, অধ্যায়ের নাম প্রদর্শিত হবে এবং ক্লিক করা হলে অধ্যায়টি নেভিগেট করা হবে।

সারসংক্ষেপ

উল্টানো পূর্ণ-পাঠ্য অনুসন্ধান সম্পূর্ণরূপে সম্মুখ প্রান্তে প্রয়োগ করা হয়েছে, কোনো সার্ভারের প্রয়োজন নেই। এটি ছোট এবং মাঝারি আকারের ওয়েবসাইট যেমন নথি এবং ব্যক্তিগত ব্লগের জন্য খুব উপযুক্ত।

i18n.site ওপেন সোর্স স্ব-উন্নত বিশুদ্ধ ফ্রন্ট-এন্ড অনুসন্ধান, আকারে ছোট এবং দ্রুত প্রতিক্রিয়া, বর্তমান বিশুদ্ধ ফ্রন্ট-এন্ড ফুল-টেক্সট অনুসন্ধানের ত্রুটিগুলি সমাধান করে এবং আরও ভাল ব্যবহারকারীর অভিজ্ঞতা প্রদান করে।