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

جستجو با اپن سرچ

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

سروری برای گفتگو

هر نمونه‌ای که با خوشه گفتگو می‌کند انتظار دارد سروری روی http://localhost:9200 باشد. ساده‌ترین راه داکر است: docker run -p 9200:9200 -e discovery.type=single-node -e DISABLE_SECURITY_PLUGIN=true opensearchproject/opensearch:2.17.1. پشت این صفحه سروری نیست، پس این نمونه‌ها را مترجم بررسی می‌کند و خروجی‌ای را نشان می‌دهند که هنگام اجرای پشت سر هم روی یک اپن سرچ ۲.۱۷.۱ واقعی چاپ کردند. نمونه‌هایی که فقط درخواست می‌سازند یا پاسخ می‌خوانند در هر ساخت سایت اجرا می‌شوند.

این بسته بخشی از کتابخانه‌ی استاندارد است و به نصب چیز دیگری نیاز ندارد. آن را با واردسازی دیتابیس.اپن سرچ بیاورید و با نام اپن سرچ صدا بزنید.

اتصال

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

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

تابع ریشه:
    ک := اپن سرچ.اتصال("http://localhost:9200")
    اگر وارونه اپن سرچ.پینگ(ک):
        سرچاپ "پاسخی نیامد:"، اپن سرچ.خطا(ک)
        برگشت 1
    پایان
    آگاهی := اپن سرچ.دریافت اطلاعات(ک)
    سرچاپ آگاهی.distribution، آگاهی.version، آگاهی.cluster_name
    ه := اپن سرچ.سلامت خوشه(ک)
    سرچاپ "سلامت:"، ه.status، ه.nodes، "گره"
    برگشت 0
پایان
خروجیopensearch 2.17.1 docker-cluster سلامت: green 1 گره

یک راه‌اندازی واقعی معمولا بیشتر لازم دارد: چند گره، نام کاربری و گذرواژه، مرجع صدور گواهی خودتان و سقف زمان. آن‌ها را در یک پیکربندی بگذارید و به کارخواه تازه بدهید. کارخواه درخواست‌ها را میان گره‌ها پخش می‌کند، گره‌ای را که اتصال را رد کند یک دقیقه کنار می‌گذارد و درخواستی را که پاسخ 502، 503 یا 504 گرفته روی گره‌ی دیگری دوباره می‌فرستد. اتصال بدون وارسی گواهی برای راه‌اندازی نمایشی با گواهی خودامضاست و اتصال آمازون هر درخواست را با AWS SigV4 برای Amazon OpenSearch Service امضا می‌کند؛ برای یک مجموعه‌ی Serverless به جای سرویس دامنه از سرویس بی‌سرور استفاده کنید.

opensearch-config.salam
واردسازی دیتابیس.اپن سرچ

تابع ریشه:
    ناپایا تنظیم := اپن سرچ.پیکربندی پیش‌فرض()
    تنظیم.nodes.بیفزا("https://node2.example.com:9200, https://node3.example.com:9200")
    تنظیم.username = "app"
    تنظیم.password = "s3cret-pass"
    تنظیم.ca_file = "/etc/ssl/certs/opensearch-ca.pem"
    تنظیم.timeout_ms = 10000
    تنظیم.max_retries = 2
    ک := اپن سرچ.کارخواه تازه(تنظیم)
    سرچاپ اپن سرچ.معتبر(ک)، اپن سرچ.گره‌ها(ک)

    محلی := اپن سرچ.اتصال بدون وارسی گواهی("https://localhost:9200"، "admin"، "admin-pass")
    سرچاپ اپن سرچ.معتبر(محلی)

    آمازون := اپن سرچ.اتصال آمازون(
        "https://search-books.eu-west-1.es.amazonaws.com"، "eu-west-1"، اپن سرچ.سرویس دامنه،
        "AKIA..."، "secret-key"، ""
    )
    سرچاپ اپن سرچ.معتبر(آمازون)
پایان
خروجیtrue ["http://localhost:9200", "https://node2.example.com:9200", "https://node3.example.com:9200"] true true

نمایه و سندهایش

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

سندها متن JSON هستند و هر نوشتن یک نتیجه نوشتن با شناسه، نتیجه و نسخه برمی‌گرداند. سند تازه پس از تازه‌سازی بعدی، حدود یک ثانیه بعد، قابل جستجو می‌شود؛ تازه‌سازی با انتظار فراخوانی را تا آن لحظه نگه می‌دارد که در آزمون‌ها و اسکریپت‌ها کارآمد است. دریافت سندی را با شناسه برمی‌گرداند و مسیر جیسون مقداری را از منبع آن بیرون می‌کشد.

opensearch-documents.salam
واردسازی دیتابیس.اپن سرچ

تابع ریشه:
    ک := اپن سرچ.اتصال("http://localhost:9200")
    ناپایا ویژگی‌ها := وکتور {} برگردان وکتور<رشته>
    ویژگی‌ها.بیفزا(اپن سرچ.ویژگی("title"، "text"))
    ویژگی‌ها.بیفزا(اپن سرچ.ویژگی("author"، "keyword"))
    ویژگی‌ها.بیفزا(اپن سرچ.ویژگی("year"، "integer"))
    ویژگی‌ها.بیفزا(اپن سرچ.ویژگی("stock"، "integer"))
    سرچاپ "ساخته شد:"، اپن سرچ.ایجاد نمایه با تنظیمات(ک، "books"، 1، 0، اپن سرچ.ویژگی‌ها(ویژگی‌ها))

    ن := اپن سرچ.نمایه‌سازی با گزینه(ک، "books"، "1"، `{"title":"Shahnameh","author":"Ferdowsi","year":1010,"stock":3}`، اپن سرچ.گزینه‌ها { refresh = اپن سرچ.تازه‌سازی با انتظار })
    سرچاپ "نمایه شد:"، ن.ok، ن.result، ن.version

    د := اپن سرچ.دریافت(ک، "books"، "1")
    اگر د.found:
        سرچاپ "عنوان:"، اپن سرچ.مسیر جیسون(د.source، "title")
    پایان

    به‌روز := اپن سرچ.به‌روزرسانی(ک، "books"، "1"، `{"stock":2}`)
    سرچاپ "به‌روز شد:"، به‌روز.result، به‌روز.version

    حذف شده := اپن سرچ.حذف سند(ک، "books"، "1")
    سرچاپ "حذف شد:"، حذف شده.result
پایان
خروجیساخته شد: true نمایه شد: true created 1 عنوان: Shahnameh به‌روز شد: updated 2 حذف شد: deleted

چند سند با هم

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

opensearch-bulk.salam
واردسازی دیتابیس.اپن سرچ

تابع ریشه:
    ناپایا ب := اپن سرچ.دسته‌ای تازه()
    اپن سرچ.نمایه‌سازی دسته‌ای(ب، "books"، "1"، `{"title":"Shahnameh","author":"Ferdowsi","year":1010}`)
    اپن سرچ.نمایه‌سازی دسته‌ای(ب، "books"، "2"، `{"title":"Masnavi","author":"Rumi","year":1258}`)
    اپن سرچ.نمایه‌سازی دسته‌ای(ب، "books"، "3"، `{"title":"Golestan","author":"Saadi","year":1258}`)
    اپن سرچ.به‌روزرسانی دسته‌ای(ب، "books"، "2"، `{"stock":4}`)
    اپن سرچ.حذف دسته‌ای(ب، "books"، "99")
    سرچاپ اپن سرچ.اندازه دسته‌ای(ب)، "کنش"
    چاپ اپن سرچ.بدنه دسته‌ای(ب)
    اپن سرچ.آزادسازی دسته‌ای(ب)
پایان
خروجی5 کنش {"index":{"_index":"books","_id":"1"}} {"title":"Shahnameh","author":"Ferdowsi","year":1010} {"index":{"_index":"books","_id":"2"}} {"title":"Masnavi","author":"Rumi","year":1258} {"index":{"_index":"books","_id":"3"}} {"title":"Golestan","author":"Saadi","year":1258} {"update":{"_index":"books","_id":"2"}} {"doc":{"stock":4}} {"delete":{"_index":"books","_id":"99"}}

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

opensearch-bulk-send.salam
واردسازی دیتابیس.اپن سرچ

تابع ریشه:
    ک := اپن سرچ.اتصال("http://localhost:9200")
    ناپایا ب := اپن سرچ.دسته‌ای تازه()
    اپن سرچ.نمایه‌سازی دسته‌ای(ب، "books"، "1"، `{"title":"Shahnameh, the Book of Kings","author":"Ferdowsi","year":1010}`)
    اپن سرچ.نمایه‌سازی دسته‌ای(ب، "books"، "2"، `{"title":"Masnavi","author":"Rumi","year":1258}`)
    اپن سرچ.نمایه‌سازی دسته‌ای(ب، "books"، "3"، `{"title":"Golestan","author":"Saadi","year":1258}`)
    اپن سرچ.نمایه‌سازی دسته‌ای(ب، "books"، "4"، `{"title":"Kings and Heroes","author":"Anonymous","year":1900}`)
    پاسخ := اپن سرچ.ارسال دسته‌ای با تازه‌سازی(ک، ب، اپن سرچ.تازه‌سازی فوری)
    اپن سرچ.آزادسازی دسته‌ای(ب)
    سرچاپ پاسخ.succeeded، "ذخیره شد،"، پاسخ.failed، "شکست خورد"
    هر قلم در پاسخ.items:
        اگر وارونه قلم.ok:
            سرچاپ قلم.id، قلم.error_type، قلم.error_reason
        پایان
    پایان
پایان
خروجی4 ذخیره شد، 0 شکست خورد

ساختن پرسمان

پرسمان هم JSON است و بسته برای هر گونه‌ی رایج یک سازنده دارد. تطبیق واژه‌های یک فیلد متنی را جستجو می‌کند، واژه یک مقدار دقیق می‌خواهد و بازه، بازه صحیح و بازه تاریخ مقایسه می‌کنند. برای ترکیبشان یک پرسمان منطقی را پر کنید: must باید تطبیق بخورد و به امتیاز می‌افزاید، filter باید تطبیق بخورد ولی امتیاز نمی‌دهد، should امتیاز را بالا می‌برد و must_not کنار می‌گذارد. یک درخواست جستجو صفحه‌بندی، مرتب‌سازی و فیلدهای برگشتی را می‌افزاید؛ بدنه جستجو نشان می‌دهد چه فرستاده خواهد شد.

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

تابع ریشه:
    سرچاپ اپن سرچ.تطبیق("title"، "book of kings")
    سرچاپ اپن سرچ.واژه("author"، "Ferdowsi")
    سرچاپ اپن سرچ.بازه صحیح("year"، 1000، 1300)

    ناپایا شرط := اپن سرچ.پرسمان منطقی {}
    شرط.must.بیفزا(اپن سرچ.تطبیق("title"، "kings"))
    شرط.filter.بیفزا(اپن سرچ.بازه صحیح("year"، 1000، 1300))
    شرط.must_not.بیفزا(اپن سرچ.واژه("author"، "Anonymous"))
    سرچاپ اپن سرچ.پرسمان منطقی ساخته(شرط)

    ناپایا درخواست := اپن سرچ.درخواست جستجو { query = اپن سرچ.پرسمان منطقی ساخته(شرط)، size = 5 }
    درخواست.sort.بیفزا(اپن سرچ.مرتب نزولی("year"))
    درخواست.source.بیفزا("title")
    سرچاپ اپن سرچ.بدنه جستجو(درخواست)
پایان
خروجی{"match":{"title":"book of kings"}} {"term":{"author":"Ferdowsi"}} {"range":{"year":{"gte":1000,"lte":1300}}} {"bool":{"must":[{"match":{"title":"kings"}}],"filter":[{"range":{"year":{"gte":1000,"lte":1300}}}],"must_not":[{"term":{"author":"Anonymous"}}]}} {"query":{"bool":{"must":[{"match":{"title":"kings"}}],"filter":[{"range":{"year":{"gte":1000,"lte":1300}}}],"must_not":[{"term":{"author":"Anonymous"}}]}},"size":5,"sort":[{"year":{"order":"desc"}}],"_source":{"includes":["title"]}}

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

خواندن یافته‌ها

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

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

تابع ریشه:
    ک := اپن سرچ.اتصال("http://localhost:9200")
    ناپایا فیلدها := وکتور {} برگردان وکتور<رشته>
    فیلدها.بیفزا("title")
    ناپایا درخواست := اپن سرچ.درخواست جستجو { query = اپن سرچ.تطبیق("title"، "kings")، size = 10 }
    درخواست.highlight = اپن سرچ.برجسته‌سازی(فیلدها)
    ر := اپن سرچ.جستجو با درخواست(ک، "books"، درخواست)
    اگر وارونه ر.ok:
        سرچاپ ر.error
        برگشت 1
    پایان
    سرچاپ ر.total، "یافته"
    هر ه در ر.hits:
        سرچاپ ه.id، ه.score، ه.source
    پایان
    برگشت 0
پایان
خروجی2 یافته 4 0.8547784 {"title":"Kings and Heroes","author":"Anonymous","year":1900} 1 0.63807404 {"title":"Shahnameh, the Book of Kings","author":"Ferdowsi","year":1010}

همین خواننده روی پاسخی که از پیش دارید هم کار می‌کند، با تجزیه جستجو. این نمونه به همین شکل این‌جا بدون سرور اجرا می‌شود:

opensearch-results.salam
واردسازی دیتابیس.اپن سرچ

تابع ریشه:
    پاسخ سرور := `{"took":3,"timed_out":false,"hits":{"total":{"value":2,"relation":"eq"},"max_score":2.1,"hits":[{"_index":"books","_id":"1","_score":2.1,"_source":{"title":"Shahnameh","author":"Ferdowsi"},"highlight":{"title":["<em>Shahnameh</em>"]}},{"_index":"books","_id":"7","_score":0.8,"_source":{"title":"Tales from the Shahnameh","author":"Anonymous"}}]}}`
    ر := اپن سرچ.تجزیه جستجو(پاسخ سرور)
    سرچاپ ر.total، "یافته در"، ر.took، "میلی‌ثانیه"
    هر ه در ر.hits:
        سرچاپ ه.id، ه.score، اپن سرچ.مسیر جیسون(ه.source، "title")، "از"، اپن سرچ.مسیر جیسون(ه.source، "author")
    پایان
    سرچاپ اپن سرچ.مسیر جیسون(ر.hits.بگیر(0).highlight، "title.0")
پایان
خروجی2 یافته در 3 میلی‌ثانیه 1 2.1 Shahnameh از Ferdowsi 7 0.8 Tales from the Shahnameh از Anonymous <em>Shahnameh</em>

شمردن با تجمیع

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

opensearch-aggs.salam
واردسازی دیتابیس.اپن سرچ

تابع ریشه:
    ناپایا تجمیع‌ها := اپن سرچ.افزودن تجمیع("{}"، "authors"، اپن سرچ.تجمیع واژه‌ها("author"، 3))
    تجمیع‌ها = اپن سرچ.افزودن تجمیع(تجمیع‌ها، "avg_year"، اپن سرچ.تجمیع میانگین("year"))
    سرچاپ اپن سرچ.بدنه جستجو(اپن سرچ.درخواست جستجو { size = 0، aggs = تجمیع‌ها })

    پاسخ سرور := `{"took":2,"hits":{"total":{"value":40,"relation":"eq"},"hits":[]},"aggregations":{"authors":{"buckets":[{"key":"Saadi","doc_count":12},{"key":"Rumi","doc_count":9},{"key":"Hafez","doc_count":7}]},"avg_year":{"value":1265.5}}}`
    ر := اپن سرچ.تجزیه جستجو(پاسخ سرور)
    هر ب در اپن سرچ.سطل‌ها(ر.aggregations، "authors"):
        سرچاپ ب.key، ب.doc_count
    پایان
    سرچاپ "میانگین سال:"، اپن سرچ.مقدار تجمیع(ر.aggregations، "avg_year")
پایان
خروجی{"size":0,"aggs":{"authors":{"terms":{"field":"author","size":3}},"avg_year":{"avg":{"field":"year"}}}} Saadi 12 Rumi 9 Hafez 7 میانگین سال: 1265.5

گذر از همه‌چیز

from و size برای صفحه‌های نخستی که آدم‌ها می‌بینند خوب است، ولی نه برای گذشتن از کل یک نمایه. برای آن با ایجاد نقطه زمانی یک نقطه‌ی زمانی باز کنید که نمایی از نمایه را ثابت نگه می‌دارد، با یک فیلد مرتب کنید و هر صفحه‌ی بعد را با search_after برابر مقدارهای مرتب‌سازی آخرین یافته بخواهید. صفحه‌ی خالی یعنی تمام؛ نقطه‌ی زمانی را با حذف نقطه زمانی ببندید.

opensearch-paging.salam
واردسازی دیتابیس.اپن سرچ

تابع ریشه:
    ک := اپن سرچ.اتصال("http://localhost:9200")
    نقطه := اپن سرچ.ایجاد نقطه زمانی(ک، "books"، "2m")
    ناپایا درخواست := اپن سرچ.درخواست جستجو { query = اپن سرچ.تطبیق همه()، size = 100، pit_id = نقطه، pit_keep_alive = "2m" }
    درخواست.sort.بیفزا(اپن سرچ.مرتب صعودی("year"))
    ناپایا دیده‌شده := 0
    ناپایا صفحه := اپن سرچ.جستجو با درخواست(ک، ""، درخواست)
    تا صفحه.hits.طول() > 0:
        دیده‌شده += صفحه.hits.طول()
        درخواست.search_after = صفحه.hits.بگیر(صفحه.hits.طول() - 1).sort
        صفحه = اپن سرچ.جستجو با درخواست(ک، ""، درخواست)
    پایان
    اپن سرچ.حذف نقطه زمانی(ک، نقطه)
    سرچاپ دیده‌شده، "کتاب"
پایان
خروجی4 کتاب

SQL و PPL

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

opensearch-sql.salam
واردسازی دیتابیس
واردسازی دیتابیس.اپن سرچ

تابع ریشه:
    ک := اپن سرچ.اتصال("http://localhost:9200")
    رابط := اپن سرچ.اتصال عمومی(ک)
    سرچاپ دیتابیس.پرسمان عدد(رابط، "SELECT COUNT(*) FROM books WHERE year > 1200")
    ردیف‌ها := رابط.پرسمان("SELECT author, COUNT(*) AS n FROM books GROUP BY author ORDER BY n DESC")
    تا ردیف‌ها.بعدی():
        سرچاپ ردیف‌ها.متن(0)، ردیف‌ها.عدد صحیح(1)
    پایان
    ردیف‌ها.بستن()

    پ := اپن سرچ.پی پی ال(ک، "source=books | where year > 1200 | stats count() by author")
    تا پ.بعدی():
        سرچاپ پ.متن(1)، پ.عدد صحیح(0)
    پایان
    پ.بستن()
پایان
خروجی3 Anonymous 1 Saadi 1 Rumi 1 Ferdowsi 1 Anonymous 1 Rumi 1 Saadi 1

جستجوی برداری

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

opensearch-vectors.salam
واردسازی دیتابیس.اپن سرچ

تابع ریشه:
    ک := اپن سرچ.اتصال("http://localhost:9200")
    روش درخواست := اپن سرچ.روش همسایه‌یابی { engine = "lucene"، space_type = "cosinesimil" }
    ناپایا افزوده := وکتور {} برگردان وکتور<رشته>
    افزوده.بیفزا(اپن سرچ.ویژگی("name"، "text"))
    اپن سرچ.ایجاد نمایه(ک، "places"، اپن سرچ.بدنه نمایه همسایه‌یابی("embedding"، 3، روش درخواست، افزوده))
    اپن سرچ.نمایه‌سازی(ک، "places"، "1"، `{"name":"Naderi Cafe","embedding":[0.1,0.9,0.2]}`)
    اپن سرچ.تازه‌سازی(ک، "places")

    ناپایا ز := وکتور {} برگردان وکتور<اعشار۶۴>
    ز.بیفزا(0.1)
    ز.بیفزا(0.8)
    ز.بیفزا(0.3)
    ر := اپن سرچ.جستجو(ک، "places"، اپن سرچ.نزدیک‌ترین همسایه‌ها("embedding"، ز، 3))
    هر ه در ر.hits:
        سرچاپ ه.id، ه.score، ه.source
    پایان
پایان
خروجی1 0.99514455 {"name":"Naderi Cafe","embedding":[0.1,0.9,0.2]}

وقتی چیزی خراب می‌شود

هیچ فراخوانی برنامه‌ی شما را متوقف نمی‌کند. فراخوانی ناموفق نادرست، ۱- یا نتیجه‌ی خالی برمی‌گرداند و کارخواه آن‌چه رخ داده را به یاد می‌سپارد: وضعیت وضعیت HTTP آخرین درخواست است (وقتی پاسخی نیامد ۰)، خطا پیامی خواناست و نوع خطا و علت خطا همان چیزی‌اند که اپن سرچ گفته، مثل version_conflict_engine_exception. نشانی نادرست هنگام ساختن کارخواه گرفته می‌شود و معتبر آن را می‌گوید.

opensearch-errors.salam
واردسازی دیتابیس.اپن سرچ

تابع ریشه:
    ناپایا تنظیم := اپن سرچ.پیکربندی پیش‌فرض()
    تنظیم.nodes = وکتور {} برگردان وکتور<رشته>
    تنظیم.nodes.بیفزا("http://127.0.0.1:1")
    تنظیم.max_retries = 0
    ک := اپن سرچ.کارخواه تازه(تنظیم)
    سرچاپ "پیکربندی معتبر:"، اپن سرچ.معتبر(ک)

    د := اپن سرچ.دریافت(ک، "books"، "1")
    سرچاپ "پیدا شد:"، د.found
    سرچاپ "وضعیت:"، اپن سرچ.وضعیت(ک)
    سرچاپ "خطا:"، اپن سرچ.خطا(ک)

    خراب := اپن سرچ.اتصال("ftp://example.com")
    سرچاپ "پیکربندی معتبر:"، اپن سرچ.معتبر(خراب)، "|"، اپن سرچ.خطا(خراب)
پایان
خروجیپیکربندی معتبر: true پیدا شد: false وضعیت: 0 خطا: http://127.0.0.1:1: could not connect to 127.0.0.1:1 پیکربندی معتبر: false | the node url could not be parsed: ftp://example.com

گام بعد

راهنمای بسته‌ی اپن سرچ همه‌ی تابع‌ها را با نمونه فهرست می‌کند، از جمله الگوهای نمایه، نام‌های مستعار، تصویر لحظه‌ای، خط لوله‌ی ورودی، سیاست‌های ISM، افزونه‌ی امنیت، هشدار و ML Commons. برای هر چه بسته تابعی برایش ندارد، انجام هر درخواستی را که بنویسید می‌فرستد.