brief: | يدعم موقع i18n.site الآن البحث عن النص الكامل بدون خادم.
تقدم هذه المقالة تطبيق تقنية البحث عن النص الكامل للواجهة الأمامية، بما في ذلك الفهرس المقلوب الذي تم إنشاؤه بواسطة IndexedDB، والبحث عن البادئات، وتحسين تجزئة الكلمات، والدعم متعدد اللغات.
بالمقارنة مع الحلول الحالية، فإن البحث عن النص الكامل للواجهة الأمامية النقية لـ i18n.site صغير الحجم وسريع، ومناسب لمواقع الويب الصغيرة والمتوسطة الحجم مثل المستندات والمدونات، ومتاح دون اتصال بالإنترنت.
بعد عدة أسابيع من التطوير، i18n.site (أداة إنشاء موقع ويب ثابتة تمامًا markdown multilingualtranslation & ) تدعم الآن البحث عن النص الكامل في الواجهة الأمامية.
ستشارك هذه المقالة التنفيذ الفني لبحث النص الكامل للواجهة الأمامية i18n.site
، قم بزيارة i18n.site
كود البحث مفتوح : / الواجهة التفاعلية
بالنسبة لمواقع الويب الثابتة البحتة الصغيرة والمتوسطة الحجم، مثل المستندات/المدونات الشخصية، يعد إنشاء واجهة خلفية للبحث عن النص الكامل ذاتية البناء أمرًا ثقيلًا للغاية، ويعتبر البحث عن النص الكامل بدون خدمة هو الخيار الأكثر شيوعًا.
تنقسم حلول البحث عن النص الكامل بدون خادم إلى فئتين عريضتين:
أولاً algolia.com يوفر مقدمو خدمات البحث التابعون لجهات خارجية مكونات أمامية للبحث عن النص الكامل.
تتطلب مثل هذه الخدمات الدفع بناءً على حجم البحث، وغالبًا ما تكون غير متاحة للمستخدمين في الصين القارية بسبب مشكلات مثل امتثال موقع الويب.
لا يمكن استخدامه دون الاتصال بالإنترنت، ولا يمكن استخدامه على الإنترانت، وله قيود كبيرة. هذه المقالة لا تناقش الكثير.
والثاني هو البحث عن النص الكامل للواجهة الأمامية.
في الوقت الحاضر، تشتمل عمليات البحث عن النص الكامل الشائعة في الواجهة الأمامية على lunrjs و ElasticLunr.js (استنادًا إلى lunrjs
تطوير ثانوي).
lunrjs
هناك طريقتان لبناء الفهارس، ولكل منهما مشاكله الخاصة.
ملفات الفهرس المعدة مسبقًا
ولأن الفهرس يحتوي على كلمات من جميع المستندات، فهو كبير الحجم. عند إضافة مستند أو تعديله، يجب تحميل ملف فهرس جديد. سيزيد من وقت انتظار المستخدم ويستهلك الكثير من النطاق الترددي.
قم بتحميل المستندات وإنشاء الفهارس بسرعة
يعد إنشاء الفهرس مهمة مكثفة من الناحية الحسابية، وستؤدي إعادة إنشاء الفهرس في كل مرة تقوم فيها بالوصول إليه إلى حدوث تأخيرات واضحة وتجربة مستخدم سيئة.
بالإضافة إلى lunrjs
، هناك بعض الحلول الأخرى للبحث عن النص الكامل، مثل :
fusejs ، حساب التشابه بين السلاسل للبحث.
أداء هذا الحل ضعيف للغاية ولا يمكن استخدامه للبحث عن النص الكامل (انظر Fuse.js يستغرق الاستعلام الطويل أكثر من 10 ثانية، وكيفية تحسينه؟ ).
TinySearch ، استخدم مرشح Bloom للبحث، ولا يمكن استخدامه للبحث عن البادئة (على سبيل المثال، أدخل goo
، ابحث good
، google
)، ولا يمكن تحقيق تأثير إكمال تلقائي مماثل.
نظرًا لأوجه القصور في الحلول الحالية، طورت i18n.site
حلاً جديدًا للبحث عن النص الكامل للواجهة الأمامية، والذي يتميز بالخصائص التالية :
gzip
هو 6.9KB
(للمقارنة حجم lunrjs
هو 25KB
).indexedb
، والذي يستهلك ذاكرة أقل ويكون سريعًا.أدناه، سيتم عرض 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()
في:
/\p{P}/
هو تعبير عادي يطابق علامات الترقيم وتشمل الرموز المطابقة المحددة ما يلي: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _
{ | } .</p><ul style=";text-align:right;direction:rtl"><li style=";text-align:right;direction:rtl">
split('.')لأن تجزئة كلمة المتصفح
Firefoxلا تقسم
. ` .
تم إنشاء 5 جداول لتخزين الكائنات في IndexedDB
:
word
الكلمات : id -doc
url - : id - رقم الإصدارdocWord
مجموعة من الوثيقة id - id :prefix
مجموعة من البادئة - id :rindex
: id - Document id : مجموعة من أرقام الأسطرقم بتمرير مصفوفة المستند url
ورقم الإصدار ver
، وابحث عما إذا كان المستند موجودًا في الجدول doc
إذا لم يكن موجودًا، فقم بإنشاء فهرس مقلوب. وفي الوقت نفسه، قم بإزالة الفهرس المقلوب لتلك المستندات التي لم يتم تمريرها.
بهذه الطريقة، يمكن تحقيق الفهرسة المتزايدة وتقليل مقدار الحساب.
في التفاعل الأمامي، يمكن عرض شريط تقدم التحميل الخاص بالفهرس لتجنب التأخير عند التحميل لأول مرة، راجع "شريط التقدم مع الرسوم المتحركة، بناءً على تطبيق واحد progress + Pure css " الإنجليزية / الصينية .
تم 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
بحث أمامي نقي مفتوح المصدر تم تطويره ذاتيًا، صغير الحجم وسريع الاستجابة، يحل عيوب البحث عن النص الكامل الحالي للواجهة الأمامية النقية ويوفر تجربة مستخدم أفضل.