درس ۲۵ از ۲۸ · دیتابیس

جستجو با تایپ‌سنس

بیشتر برنامه‌ها یک جعبه‌ی جستجو لازم دارند، و جستجوی خوب غلط تایپی را می‌بخشد، بهترین نتیجه را اول می‌آورد و در چند میلی‌ثانیه پاسخ می‌دهد. تایپ‌سنس یک موتور جستجوی متن‌باز است که برای همین کار ساخته شده، و بسته‌ی دیتابیس.تایپسنس همه‌ی آن را در اختیار برنامه‌ی سلام می‌گذارد. این درس یک فهرست کوچک کتاب را از یک سرور خالی تا کلیدی که یک صفحه‌ی وب بتواند به کار ببرد پیش می‌برد.

راه‌اندازی سرور

تایپ‌سنس برنامه‌ای جداست که داده‌ها را در نمایه‌ی خودش نگه می‌دارد. ساده‌ترین راه برای اجرای آن روی رایانه‌ی خودتان داکر است. مقدار --api-key کلید مدیری است که برنامه‌ی شما با هر درخواست می‌فرستد؛ بیرون از رایانه‌ی خودتان به جای xyz یک رمز واقعی بگذارید.

docker run -p 8108:8108 typesense/typesense:30.2 --data-dir /tmp --api-key=xyz

نمونه‌های این درس با همین سرور کار می‌کنند، پس هنگام ساختن این سایت کامپایلر آن‌ها را بررسی می‌کند اما اجرا نمی‌کند. خروجی زیر هر نمونه همان چیزی است که روی یک سرور واقعی تایپ‌سنس ۳۰.۲ و به ترتیب درس چاپ کرد: هر نمونه روی داده‌هایی ساخته می‌شود که نمونه‌های قبلی به جا گذاشته‌اند.

وصل شدن

تایپسنس.جدید نشانی سرور و کلید را می‌گیرد و یک کلاینت برمی‌گرداند. هنوز چیزی فرستاده نشده است؛ هر تابعی که با سرور کار می‌کند کلاینت را اول و یک خطا را آخر می‌گیرد. اگر فراخوانی شکست بخورد خطا پر می‌شود: موفق می‌گوید کار انجام شد یا نه، متن خطا یک سطر خوانا می‌دهد، و پیدا نشد و تداخل دارد به دو پرسشی پاسخ می‌دهند که کد بیشتر از همه می‌پرسد. وقتی کارتان تمام شد کلاینت را با آزادسازی رها کنید.

search-connect.salam
واردسازی دیتابیس.تایپسنس

تابع ریشه:
    ناپایا ک := تایپسنس.جدید("http://localhost:8108"، "xyz")
    دیرکن تایپسنس.آزادسازی(ک)
    ناپایا خ := تایپسنس.خطا {}

    اگر وارونه تایپسنس.سلامت(ک، خ):
        سرچاپ "تایپ‌سنس آماده نیست:"، تایپسنس.متن خطا(خ)
        برگشت ۱
    پایان
    سرچاپ "وصل شد، نسخه‌ی سرور"، تایپسنس.نسخه سرور(ک، خ)

    _ := تایپسنس.دریافت مجموعه(ک، "no_such_collection"، خ)
    اگر وارونه تایپسنس.موفق(خ):
        سرچاپ "وضعیت"، خ.status، "پیدا نشد:"، تایپسنس.پیدا نشد(خ)
        سرچاپ تایپسنس.متن خطا(خ)
    پایان
پایان
خروجیوصل شد، نسخه‌ی سرور 30.2 وضعیت 404 پیدا نشد: true typesense 404: Collection not found

خطا سه بخش کاربردی دارد: status وضعیت HTTP است (و اگر اصلا به سرور نرسیدیم صفر)، kind نوع شکست را می‌گوید و message متنی است که سرور فرستاده.

مجموعه و فیلد

سندها در یک مجموعه نگه داشته می‌شوند و طرح مجموعه می‌گوید چه فیلدهایی دارد و نوع هر کدام چیست. فیلد جدید یک فیلد ساده می‌سازد، فیلد دسته بندی فیلدی که می‌شود مقدارهایش را شمرد، و با یک فیلد کامل بقیه‌ی گزینه‌ها را می‌گذارید: optional برای فیلدی که بعضی سندها ندارند، sort، locale برای زبان متن، infix برای یافتن از میان واژه و چیزهای دیگر. نوع‌ها ثابت‌هایی مثل نوع متن، نوع عدد۳۲، نوع اعشاری، نوع آرایه متن و نوع نقطه جغرافیایی هستند.

search-schema.salam
واردسازی دیتابیس.تایپسنس

تابع ریشه:
    ناپایا ک := تایپسنس.جدید("http://localhost:8108"، "xyz")
    دیرکن تایپسنس.آزادسازی(ک)
    ناپایا خ := تایپسنس.خطا {}
    _ := تایپسنس.حذف مجموعه(ک، "lesson_books"، خ)

    ناپایا طرح := تایپسنس.طرح { name = "lesson_books"، default_sorting_field = "year" }
    طرح.fields.بیفزا(تایپسنس.فیلد جدید("title"، تایپسنس.نوع متن))
    طرح.fields.بیفزا(تایپسنس.فیلد جدید("author"، تایپسنس.نوع متن))
    طرح.fields.بیفزا(تایپسنس.فیلد دسته بندی("genre"، تایپسنس.نوع متن))
    طرح.fields.بیفزا(تایپسنس.فیلد جدید("year"، تایپسنس.نوع عدد۳۲))
    طرح.fields.بیفزا(تایپسنس.فیلد { name = "rating"، kind = تایپسنس.نوع اعشاری، optional = درست })

    مجموعه := تایپسنس.ساخت مجموعه(ک، طرح، خ)
    اگر وارونه تایپسنس.موفق(خ):
        سرچاپ تایپسنس.متن خطا(خ)
        برگشت ۱
    پایان
    سرچاپ "ساخته شد"، مجموعه.name، "با"، مجموعه.fields.طول()، "فیلد"
    هر فیلد در مجموعه.fields:
        سرچاپ " "، فیلد.name، فیلد.kind، "دسته‌بندی:"، فیلد.facet
    پایان
پایان
خروجیساخته شد lesson_books با 5 فیلد title string دسته‌بندی: false author string دسته‌بندی: false genre string دسته‌بندی: true year int32 دسته‌بندی: false rating float دسته‌بندی: false

یک default_sorting_field عددی ترتیب را وقتی جستجو ترتیبی نخواسته تعیین می‌کند. بعدا با افزودن فیلدها و حذف فیلدها مجموعه را تغییر دهید، با دریافت مجموعه و فهرست مجموعه ها نگاهش کنید و با حذف مجموعه پاکش کنید. برای ساختن دوباره‌ی یک مجموعه بی هیچ وقفه، نسخه‌ی تازه را کنار نسخه‌ی قدیمی بسازید و یک نام مستعار را با درج نام مستعار جابه‌جا کنید؛ برنامه‌هایی که با نام مستعار جستجو می‌کنند متوجه جابه‌جایی نمی‌شوند.

افزودن سند

سند یک شیء JSON است که فیلدهایش با طرح جور است. می‌توانید JSON را خودتان بنویسید، اما معمولا داده از پیش در یک ساختار است. درون ریزی از نوع یک وکتور از هر ساختاری را می‌گیرد، هر کدام را با رمزگذار خود کامپایلر به JSON تبدیل می‌کند و همه را در یک درخواست می‌فرستد. دریافت سند به نوع برعکس کار می‌کند و سند ذخیره‌شده را به ساختار شما برمی‌گرداند. با @json نام فیلد در JSON انگلیسی می‌ماند و نام فیلد در کد فارسی.

search-import.salam
واردسازی دیتابیس.تایپسنس

ساختار کتاب:
    @json "id"
    همگانی شناسه: رشته = ""
    @json "title"
    همگانی عنوان: رشته = ""
    @json "author"
    همگانی نویسنده: رشته = ""
    @json "genre"
    همگانی گونه: رشته = ""
    @json "year"
    همگانی سال: صحیح = ۰
پایان

تابع ریشه:
    ناپایا ک := تایپسنس.جدید("http://localhost:8108"، "xyz")
    دیرکن تایپسنس.آزادسازی(ک)
    ناپایا خ := تایپسنس.خطا {}

    ناپایا کتاب‌ها := وکتور {} برگردان وکتور<کتاب>
    کتاب‌ها.بیفزا(کتاب { شناسه = "1"، عنوان = "کلیدر"، نویسنده = "محمود دولت‌آبادی"، گونه = "رمان"، سال = ۱۹۸۴ })
    کتاب‌ها.بیفزا(کتاب { شناسه = "2"، عنوان = "جای خالی سلوچ"، نویسنده = "محمود دولت‌آبادی"، گونه = "رمان"، سال = ۱۹۷۹ })
    کتاب‌ها.بیفزا(کتاب { شناسه = "3"، عنوان = "بوف کور"، نویسنده = "صادق هدایت"، گونه = "داستان"، سال = ۱۹۳۶ })
    کتاب‌ها.بیفزا(کتاب { شناسه = "4"، عنوان = "سووشون"، نویسنده = "سیمین دانشور"، گونه = "رمان"، سال = ۱۹۶۹ })
    کتاب‌ها.بیفزا(کتاب { شناسه = "5"، عنوان = "شازده احتجاب"، نویسنده = "هوشنگ گلشیری"، گونه = "داستان"، سال = ۱۹۶۹ })
    ن := تایپسنس.درون ریزی از نوع(ک، "lesson_books"، کتاب‌ها، تایپسنس.گزینه های نوشتن { action = تایپسنس.کنش درج }، خ)
    سرچاپ "وارد شد"، ن.success، "ناموفق"، ن.failed

    _ := تایپسنس.ساخت سند(ک، "lesson_books"، `{"id": "6", "title": "گلستان", "author": "سعدی", "genre": "نثر", "year": "1258"}`، خ)
    سرچاپ "نوع نادرست:"، تایپسنس.متن خطا(خ)
    سرچاپ تایپسنس.درج سند(ک، "lesson_books"، `{"id": "6", "title": "گلستان", "author": "سعدی", "genre": "نثر", "year": 1258}`، خ)

    ناپایا ب := کتاب {}
    اگر تایپسنس.دریافت سند به نوع(ک، "lesson_books"، "1"، ب، خ):
        سرچاپ "خوانده شد:"، ب.عنوان، "از"، ب.نویسنده
    پایان
    سرچاپ تایپسنس.به‌روزرسانی سند(ک، "lesson_books"، "6"، `{"rating": 4.9}`، خ)
پایان
خروجیوارد شد 5 ناموفق 0 نوع نادرست: typesense 400: Field `year` must be an int32. {"author":"سعدی","genre":"نثر","id":"6","title":"گلستان","year":1258} خوانده شد: کلیدر از محمود دولت‌آبادی {"author":"سعدی","genre":"نثر","id":"6","rating":4.9,"title":"گلستان","year":1258}

درون‌ریزی حتی وقتی بعضی سندها شکست بخورند پاسخ می‌دهد، پس failed را بررسی کنید؛ errors هر خط ناموفق را با دلیلش می‌آورد. گزینه های نوشتن می‌گوید با سندهای موجود چه شود: کنش ساخت آن‌ها را نمی‌پذیرد، کنش درج جایگزینشان می‌کند و کنش به‌روزرسانی و کنش جایگذاری فقط فیلدهای فرستاده‌شده را عوض می‌کنند. برای یک سند در هر بار ساخت سند، درج سند، به‌روزرسانی سند و حذف سند هست، و حذف با پالایه و به‌روزرسانی با پالایه چند سند را با هم تغییر می‌دهند.

جستجوی جدید پارامترهای یک جستجو را می‌سازد: متنی که دنبالش هستید و فیلدهایی که باید در آن‌ها گشت. * به جای متن همه‌ی سندها را می‌آورد و همراه یک پالایه به کار می‌آید. نتیجه found دارد، یعنی تعداد یافته‌ها، و hits، یکی برای هر سند در این صفحه؛ document هر یافته خود سند به شکل JSON است.

search-query.salam
واردسازی دیتابیس.تایپسنس

تابع نشان(برچسب: رشته، ن: تایپسنس.نتیجه جستجو):
    سرچاپ برچسب، "پیدا شد"، ن.found
    هر ی در ن.hits:
        سرچاپ "   "، ی.document
    پایان
پایان

تابع ریشه:
    ناپایا ک := تایپسنس.جدید("http://localhost:8108"، "xyz")
    دیرکن تایپسنس.آزادسازی(ک)
    ناپایا خ := تایپسنس.خطا {}

    نشان("دولت‌آبادی:"، تایپسنس.جستجو(ک، "lesson_books"، تایپسنس.جستجوی جدید("دولت‌آبادی"، "author")، خ))
    نشان("غلط تایپی:"، تایپسنس.جستجو(ک، "lesson_books"، تایپسنس.جستجوی جدید("سوشون"، "title")، خ))

    ناپایا ج := تایپسنس.جستجوی جدید("*"، "")
    ج.filter_by = "genre:=رمان && year:<1980"
    ج.sort_by = "year:desc"
    ج.include_fields = "title,year"
    نشان("با پالایه:"، تایپسنس.جستجو(ک، "lesson_books"، ج، خ))

    ناپایا ب := تایپسنس.جستجوی جدید("دولت‌آبادی"، "author,title")
    ب.per_page = ۱
    ن := تایپسنس.جستجو(ک، "lesson_books"، ب، خ)
    سرچاپ "صفحه"، ن.page، "از"، ن.found، "نتیجه، برجسته:"، تایپسنس.برجسته(ن.hits.بگیر(۰)، "author")
پایان
خروجیدولت‌آبادی: پیدا شد 2 {"author":"محمود دولت‌آبادی","genre":"رمان","id":"1","title":"کلیدر","year":1984} {"author":"محمود دولت‌آبادی","genre":"رمان","id":"2","title":"جای خالی سلوچ","year":1979} غلط تایپی: پیدا شد 1 {"author":"سیمین دانشور","genre":"رمان","id":"4","title":"سووشون","year":1969} با پالایه: پیدا شد 2 {"title":"جای خالی سلوچ","year":1979} {"title":"سووشون","year":1969} صفحه 1 از 2 نتیجه، برجسته: محمود <mark>دولت‌آبادی</mark>

سه چیز رخ داد که لازم نبود بخواهید. سوشون باز هم سووشون را پیدا کرد، چون تایپ‌سنس یکی دو غلط تایپی در هر واژه را می‌بخشد. بهترین تطابق اول آمد. و برجسته نشان می‌دهد کدام بخش فیلد جور شد. پارامترهای دیگر فیلدهای پارامترهای جستجو هستند: filter_by و sort_by مثل نمونه، page و per_page برای صفحه‌بندی، include_fields برای برگرداندن داده‌ی کمتر و num_typos برای سخت‌گیری بیشتر. پارامتری که فیلد جدا ندارد با تایپسنس.تنظیم پارامتر(ج، نام، مقدار) فرستاده می‌شود.

می‌خواهیدبنویسید
فقط بعضی سندهاج.filter_by = "year:>1950 && genre:=[رمان, داستان]"
ترتیبی دیگرج.sort_by = "year:desc"
صفحه‌ی سوم، ده‌تا در هر صفحهج.page = ۳ و ج.per_page = ۱۰
هیچ غلط تایپیج.num_typos = "0"
ساختارهای خودتان به جای JSONتایپسنس.یافته ها به نوع(نتیجه، کتاب‌ها، خ)

دسته‌بندی و گروه

جستجوی یک فروشگاه معمولا ستونی کناری دارد: چند نتیجه کفش است و چند تا پیراهن، چند تا زیر صد هزار تومان. این شمارش‌ها دسته‌بندی هستند. نام فیلدهای دسته‌بندی را در facet_by بگذارید تا هر نتیجه برای هر کدام یک دسته داشته باشد، با مقدارها و تعداد یافته‌هایی که هر مقدار را دارند. group_by به پرسش دیگری پاسخ می‌دهد: برای هر مقدار چند یافته‌ی برتر را نگه می‌دارد، این‌جا کهن‌ترین کتاب هر گونه.

search-facets.salam
واردسازی رشته
واردسازی دیتابیس.تایپسنس

تابع ریشه:
    ناپایا ک := تایپسنس.جدید("http://localhost:8108"، "xyz")
    دیرکن تایپسنس.آزادسازی(ک)
    ناپایا خ := تایپسنس.خطا {}

    ناپایا ج := تایپسنس.جستجوی جدید("*"، "")
    ج.facet_by = "genre"
    ن := تایپسنس.جستجو(ک، "lesson_books"، ج، خ)
    هر د در ن.facets:
        هر ش در د.counts:
            سرچاپ د.field_name، ش.value، ش.count
        پایان
    پایان

    ناپایا گ := تایپسنس.جستجوی جدید("*"، "")
    گ.group_by = "genre"
    گ.group_limit = ۱
    گ.sort_by = "year:asc"
    نگ := تایپسنس.جستجو(ک، "lesson_books"، گ، خ)
    هر گروه در نگ.groups:
        سرچاپ "کهن‌ترین"، رشته.بپیوند(گروه.key، "") + ":"، گروه.hits.بگیر(۰).document
    پایان
پایان
خروجیgenre رمان 3 genre داستان 2 genre نثر 1 کهن‌ترین نثر: {"author":"سعدی","genre":"نثر","id":"6","rating":4.9,"title":"گلستان","year":1258} کهن‌ترین داستان: {"author":"صادق هدایت","genre":"داستان","id":"3","title":"بوف کور","year":1936} کهن‌ترین رمان: {"author":"سیمین دانشور","genre":"رمان","id":"4","title":"سووشون","year":1969}

چند جستجو در یک درخواست

صفحه‌ای که هم‌زمان در کتاب‌ها و نویسنده‌ها جستجو می‌کند به دو رفت و برگشت نیاز ندارد. جستجوی چندگانه فهرستی از درخواست جستجو را در یک درخواست می‌فرستد و برای هر جستجو یک نتیجه برمی‌گرداند؛ هر نتیجه code و error خودش را دارد، پس یک جستجوی نادرست بقیه را خراب نمی‌کند. پارامترهای مشترک روی همه‌ی جستجوها اعمال می‌شوند. جستجوی اجتماع یک گام جلوتر می‌رود و یافته‌های همه‌ی جستجوها را در یک فهرست رتبه‌بندی‌شده می‌ریزد، و هر یافته می‌گوید کدام جستجو پیدایش کرد.

search-multi.salam
واردسازی دیتابیس.تایپسنس

تابع ریشه:
    ناپایا ک := تایپسنس.جدید("http://localhost:8108"، "xyz")
    دیرکن تایپسنس.آزادسازی(ک)
    ناپایا خ := تایپسنس.خطا {}

    ناپایا جستجوها := وکتور {} برگردان وکتور<تایپسنس.درخواست جستجو>
    جستجوها.بیفزا(تایپسنس.درخواست جستجو { collection = "lesson_books"، params = تایپسنس.جستجوی جدید("کلیدر"، "title") })
    جستجوها.بیفزا(تایپسنس.درخواست جستجو { collection = "lesson_books"، params = تایپسنس.جستجوی جدید("هدایت"، "author") })
    مشترک := تایپسنس.پارامترهای جستجو { per_page = ۳ }

    هر ن در تایپسنس.جستجوی چندگانه(ک، جستجوها، مشترک، خ):
        سرچاپ "جستجو پیدا کرد"، ن.found
    پایان
    اج := تایپسنس.جستجوی اجتماع(ک، جستجوها، مشترک، خ)
    سرچاپ "اجتماع پیدا کرد"، اج.found
    هر ی در اج.hits:
        سرچاپ "  از جستجوی"، ی.search_index، ی.document
    پایان
پایان
خروجیجستجو پیدا کرد 1 جستجو پیدا کرد 1 اجتماع پیدا کرد 2 از جستجوی 0 {"author":"محمود دولت‌آبادی","genre":"رمان","id":"1","title":"کلیدر","year":1984} از جستجوی 1 {"author":"صادق هدایت","genre":"داستان","id":"3","title":"بوف کور","year":1936}

مترادف و گزینش

موتور جستجو فقط واژه‌های سندهای شما را می‌شناسد. یک دسته‌ی مترادف به آن یاد می‌دهد که بعضی واژه‌ها یک معنی دارند، پس جستجوی داستان بلند کتاب‌هایی را هم پیدا می‌کند که گونه‌شان رمان است. دسته‌ی گزینش برای پرسش‌هایی است که بیشتر از همه برایتان مهم‌اند: وقتی پرسشی با یک قاعده جور شود، قاعده می‌تواند سندهایی را در جای مشخصی سنجاق کند، سندهایی را پنهان کند، پالایه بیفزاید یا ترتیب را عوض کند. هر دو دسته یک بار ساخته می‌شوند و سپس به هر مجموعه‌ای که باید از آن‌ها استفاده کند وصل می‌شوند.

search-tuning.salam
واردسازی دیتابیس.تایپسنس

تابع ریشه:
    ناپایا ک := تایپسنس.جدید("http://localhost:8108"، "xyz")
    دیرکن تایپسنس.آزادسازی(ک)
    ناپایا خ := تایپسنس.خطا {}

    ناپایا واژه‌ها := وکتور {} برگردان وکتور<رشته>
    واژه‌ها.بیفزا("رمان")
    واژه‌ها.بیفزا("داستان بلند")
    ناپایا مترادف‌ها := وکتور {} برگردان وکتور<تایپسنس.مترادف>
    مترادف‌ها.بیفزا(تایپسنس.مترادف { id = "novel"، synonyms = واژه‌ها })
    _ := تایپسنس.درج دسته مترادف(ک، "lesson_words"، مترادف‌ها، خ)

    ناپایا سنجاق‌ها := وکتور {} برگردان وکتور<تایپسنس.سنجاق>
    سنجاق‌ها.بیفزا(تایپسنس.سنجاق { id = "2"، position = ۱ })
    ناپایا قاعده‌ها := وکتور {} برگردان وکتور<تایپسنس.قاعده گزینش>
    قاعده‌ها.بیفزا(تایپسنس.قاعده گزینش { id = "salouch-first"، query = "دولت‌آبادی"، match_type = تایپسنس.تطابق دقیق، includes = سنجاق‌ها })
    _ := تایپسنس.درج دسته گزینش(ک، "lesson_rules"، قاعده‌ها، خ)

    _ := تایپسنس.به‌روزرسانی مجموعه(ک، "lesson_books"، `{"synonym_sets": ["lesson_words"], "curation_sets": ["lesson_rules"]}`، خ)
    سرچاپ "داستان بلند"، تایپسنس.جستجو(ک، "lesson_books"، تایپسنس.جستجوی جدید("داستان بلند"، "genre")، خ).found، "کتاب پیدا می‌کند"
    ن := تایپسنس.جستجو(ک، "lesson_books"، تایپسنس.جستجوی جدید("دولت‌آبادی"، "author")، خ)
    سرچاپ "نخستین یافته:"، ن.hits.بگیر(۰).document، "گزینش‌شده:"، ن.hits.بگیر(۰).curated
پایان
خروجیداستان بلند 3 کتاب پیدا می‌کند نخستین یافته: {"author":"محمود دولت‌آبادی","genre":"رمان","id":"2","title":"جای خالی سلوچ","year":1979} گزینش‌شده: true

نشانه‌ی curated به صفحه‌ی شما می‌گوید که یافته را یک قاعده جا داده، مثلا برای نوشتن برچسب «پیشنهاد ویژه». یک جستجو می‌تواند قاعده‌ها را با تایپسنس.تنظیم پارامتر(ج، "enable_curations"، "false") خاموش کند. تایپ‌سنس ۲۹ و قدیمی‌تر مترادف‌ها و قاعده‌ها را به جای دسته، برای هر مجموعه جدا نگه می‌دارد؛ برای آن سرورها درج مترادف و درج بازنویسی را به کار ببرید.

کلیدی برای مرورگر

کلید مدیر هر کاری می‌تواند بکند، پس هرگز نباید به یک صفحه‌ی وب برسد. کلید فقط جستجو کلیدی می‌سازد که فقط می‌تواند در مجموعه‌هایی که نام می‌برید جستجو کند. کلید محدود از این هم جلوتر می‌رود: کلید جستجوی محدود یک کلید جستجو را همراه پارامترهای جستجو امضا می‌کند، مثلا پالایه‌ای که هر کاربر را به داده‌ی خودش محدود می‌کند. این کلید در خود برنامه و بدون هیچ درخواستی به سرور ساخته می‌شود، و مرورگر نمی‌تواند پالایه را بردارد، چون هر تغییری امضا را خراب می‌کند.

search-keys.salam
واردسازی دیتابیس.تایپسنس

تابع ریشه:
    ناپایا مدیر := تایپسنس.جدید("http://localhost:8108"، "xyz")
    دیرکن تایپسنس.آزادسازی(مدیر)
    ناپایا خ := تایپسنس.خطا {}

    ناپایا مجموعه‌ها := وکتور {} برگردان وکتور<رشته>
    مجموعه‌ها.بیفزا("lesson_books")
    کلید := تایپسنس.کلید فقط جستجو(مدیر، "website search"، مجموعه‌ها، خ)
    سرچاپ "کلید جستجو ساخته شد، اجازه دارد:"، کلید.actions.بگیر(۰)

    محدود := تایپسنس.کلید جستجوی محدود(کلید.value، تایپسنس.پارامترهای جستجو { filter_by = "genre:=داستان" }، ۰)
    ناپایا مرورگر := تایپسنس.جدید("http://localhost:8108"، محدود)
    دیرکن تایپسنس.آزادسازی(مرورگر)
    سرچاپ "مرورگر"، تایپسنس.جستجو(مرورگر، "lesson_books"، تایپسنس.جستجوی جدید("*"، "")، خ).found، "کتاب می‌بیند"
    _ := تایپسنس.حذف سند(مرورگر، "lesson_books"، "1"، خ)
    سرچاپ "و نمی‌تواند حذف کند:"، خ.status
    _ := تایپسنس.حذف کلید(مدیر، کلید.id، خ)
پایان
خروجیکلید جستجو ساخته شد، اجازه دارد: documents:search مرورگر 2 کتاب می‌بیند و نمی‌تواند حذف کند: 401

وقتی کلید محدود را برای هر نشست جدا می‌دهید، زمان انقضا هم برایش بگذارید (آرگومان آخر، یک زمان یونیکس)، و کلیدهایی را که دیگر لازم ندارید با حذف کلید پاک کنید.

بردار و مکان

واژه تنها راه پیدا کردن چیزها نیست. فیلدی از نوع نقطه جغرافیایی عرض و طول جغرافیایی را نگه می‌دارد، و پالایه‌ای مثل location:(35.70, 51.42, 2 km) فقط چیزهای نزدیک یک نقطه را نگه می‌دارد، و ترتیب بر پایه‌ی همان نقطه نزدیک‌ترین را اول می‌آورد. فیلد بردار (فیلد بردار) فهرستی از عددها را نگه می‌دارد که یک سند را توصیف می‌کند و معمولا یک مدل یادگیری ماشین آن را ساخته، و vector_query سندهایی را پیدا می‌کند که بردارشان به بردار شما نزدیک‌تر است. با فیلد جاسازی خود تایپ‌سنس بردارها را از متن فیلدهای دیگر می‌سازد.

search-vector-geo.salam
واردسازی دیتابیس.تایپسنس

تابع ریشه:
    ناپایا ک := تایپسنس.جدید("http://localhost:8108"، "xyz")
    دیرکن تایپسنس.آزادسازی(ک)
    ناپایا خ := تایپسنس.خطا {}
    _ := تایپسنس.حذف مجموعه(ک، "lesson_places"، خ)

    ناپایا طرح := تایپسنس.طرح { name = "lesson_places" }
    طرح.fields.بیفزا(تایپسنس.فیلد جدید("name"، تایپسنس.نوع متن))
    طرح.fields.بیفزا(تایپسنس.فیلد جدید("location"، تایپسنس.نوع نقطه جغرافیایی))
    طرح.fields.بیفزا(تایپسنس.فیلد بردار("style"، ۲))
    _ := تایپسنس.ساخت مجموعه(ک، طرح، خ)
    ناپایا سندها := وکتور {} برگردان وکتور<رشته>
    سندها.بیفزا(`{"name": "کافه‌ی آرام کتابخانه", "location": [35.7019, 51.4223], "style": [0.9, 0.1]}`)
    سندها.بیفزا(`{"name": "باشگاه پرسروصدا", "location": [35.6990, 51.4180], "style": [0.1, 0.9]}`)
    سندها.بیفزا(`{"name": "چایخانه‌ی باغ", "location": [35.8040, 51.4330], "style": [0.8, 0.2]}`)
    _ := تایپسنس.درون ریزی سندها(ک، "lesson_places"، سندها، تایپسنس.گزینه های نوشتن {}، خ)

    ناپایا نزدیک := تایپسنس.جستجوی جدید("*"، "")
    نزدیک.filter_by = "location:(35.7000, 51.4200, 2 km)"
    نزدیک.sort_by = "location(35.7000, 51.4200):asc"
    نزدیک.include_fields = "name"
    هر ی در تایپسنس.جستجو(ک، "lesson_places"، نزدیک، خ).hits:
        سرچاپ "نزدیک:"، ی.document، ی.geo_distance_meters
    پایان

    ناپایا مانند := تایپسنس.جستجوی جدید("*"، "")
    مانند.vector_query = "style:([1.0, 0.0], k: 2)"
    مانند.include_fields = "name"
    هر ی در تایپسنس.جستجو(ک، "lesson_places"، مانند، خ).hits:
        سرچاپ "آرام:"، ی.document
    پایان
    _ := تایپسنس.حذف مجموعه(ک، "lesson_places"، خ)
پایان
خروجینزدیک: {"name":"باشگاه پرسروصدا"} {"location":212} نزدیک: {"name":"کافه‌ی آرام کتابخانه"} {"location":296} آرام: {"name":"کافه‌ی آرام کتابخانه"} آرام: {"name":"چایخانه‌ی باغ"}

در محیط واقعی

  • یک خوشه‌ی تایپ‌سنس چند گره دارد. نشانی همه را به خوشه جدید بدهید: گرهی که پاسخ ندهد به اندازه‌ی healthcheck_ms کنار گذاشته می‌شود و درخواست به گره بعدی می‌رود. تنظیم نزدیک‌ترین گره گرهی را تعیین می‌کند که اول امتحان شود.
  • کلاینت را با فیلدهایش تنظیم کنید: timeout_ms برای زمان یک درخواست، و retries و retry_interval_ms برای این‌که چقدر تلاش کند.
  • در جستجوها نام مستعار را به کار ببرید، نه نام مجموعه را، تا بتوانید مجموعه را بی وقفه دوباره بسازید.
  • با ساخت تصویر لحظه ای پشتیبان بگیرید، سرور را با سلامت، آمار و سنجه ها زیر نظر داشته باشید، و کلیک‌ها یا پرسش‌های پرطرفدار را با قاعده‌های تحلیل بشمارید (ساخت قاعده تحلیل و ارسال رویداد).
  • برای مسیری که این بسته تابع جدا برایش ندارد، درخواست هر روش و مسیری را با بدنه‌ی JSON می‌فرستد.

همه‌ی تابع‌ها، نوع‌ها و فیلدها با نمونه‌ی خودشان در صفحه‌ی مرجع تایپ‌سنس آمده‌اند. در مخزن هم برای هر ویژگی یک برنامه‌ی کامل و آزموده به فارسی هست، در پرونده‌هایی از tests/fa/db که نامشان با tslive_ex_ آغاز می‌شود.