استفاده از جستجوی متنی

از ویژگی‌های جستجوی متن در Cloud Firestore برای جستجوی رشته‌های خاص در یک مجموعه استفاده کنید.

قبل از اینکه شروع کنی

قبل از شروع استفاده از پرس‌وجوهای متنی، موارد زیر را انجام دهید:

  1. مطمئن شوید که به یک پایگاه داده عملیاتی سازگار با MongoDB دسترسی دارید، یا یک پایگاه داده ایجاد کنید و به آن متصل شوید .

  2. مطمئن شوید که یک فهرست متنی دارید، یا یک فهرست متنی ایجاد کنید .

مجوزهای IAM

برای ایجاد یک فهرست در Cloud Firestore ، مطمئن شوید که هر یک از نقش‌های زیر به شما اختصاص داده شده است:

  • roles/datastore.owner
  • roles/datastore.indexAdmin
  • roles/editor
  • roles/owner

برای اعطای یک نقش، به اعطای یک نقش واحد مراجعه کنید. برای اطلاعات بیشتر در مورد نقش‌های Cloud Firestore و مجوزهای مرتبط، به نقش‌های از پیش تعریف شده مراجعه کنید.

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

  • datastore.indexes.create
  • datastore.indexes.delete
  • datastore.indexes.get
  • datastore.indexes.list
  • datastore.indexes.update

اجرای یک کوئری متنی

پرس‌وجوهای متنی از عملگر $text درون یک فیلتر استفاده می‌کنند. رشته‌ی مورد نظر را در آرگومان $search مشخص کنید.

اجرای یک کوئری متنی عمومی

برای انجام یک پرس و جوی عمومی، کوئری زیر را اجرا کنید:

  # Find query
  db.cities.find({ $text: { $search: "french bread" } })

  # Aggregation query
  db.cities.aggregate([
    { $match: { $text: { $search: "french bread" } } }
  ]);

اگر اندیس شما پارتیشن‌بندی شده باشد، می‌توانید با قرار دادن پارتیشن در یک فیلتر تساوی "و" در کوئری خود، آن را بر اساس پارتیشن فیلتر کنید. برای مثال، اگر پارتیشن city داشته باشید، می‌توانید یک کوئری متنی را به صورت زیر فیلتر کنید:

db.myCollection.find( { $and: [
  { $text: { $search: "french bread" } },
  { "city": "Paris" }
] } )

همچنین می‌توانید یک مجموعه را بر اساس یک پارتیشن فیلتر کنید. برای مثال:

db.myCollection.aggregate([
 { $match: { $text: { $search: "french bread" } } },
 { "city": "Paris" }
] );

مقدار پارتیشن شما باید یک رشته باشد. فیلتر پارتیشن شما باید با استفاده از یک "و" به کوئری شما متصل شود.

زبان پرس و جو را تنظیم کنید

شما می‌توانید زبان پرس‌وجو را با استفاده از آرگومان $language تنظیم کنید. برای مثال:

  db.cities.find({ $text: { $search: "french bread", $language: "en"} })

اگر زبان پرس‌وجو را تنظیم نکنید، پرس‌وجو از زبان فهرست متن استفاده می‌کند.

پرس و جو کردن یک عبارت دقیق

برای جستجوی یک عبارت دقیق، عبارت را به صورت دنباله‌ای از کلمات که بین دو علامت نقل قول قرار گرفته‌اند، پیکربندی کنید. برای مثال:

  # Find query
  db.cities.find({ $text: { $search: "\"best french bread\"" } })

  # Aggregation query
  db.cities.aggregate([
    { $match: { $text: { $search: "\"best french bread\"" } } },
  ]);

پرس و جو برای ترکیب یک عبارت

برای دقیق‌تر کردن جستجوی خود، زنجیره‌ای از عبارات را مشخص کنید. برای مثال، جستجوی زیر اسنادی را برمی‌گرداند که با ترکیب best AND french AND ("bread" OR "is") مطابقت دارند:

  # Find query
  db.cities.find({ $text: { $search: "\"best\" \"french\" bread is" } })

  # Aggregation query
  db.cities.aggregate([
    { $match: { $text: { $search: "\"best\" \"french\" bread is" } } },
  ]);

یک اصطلاح را حذف کنید

برای حذف یک عبارت از یک پرس‌وجو، قبل از آن عبارت، یک خط تیره (-) قرار دهید:

  # Find query
  db.cities.find({ $text: { $search: "best bread -french"} })

  # Aggregation query
  db.cities.aggregate([
    { $match: { $text: { $search: "best bread -french" } } },
  ]);

محاسبه امتیاز مرتبط بودن

از عبارت {$meta: "textScore"} برای محاسبه امتیاز مرتبط بودن اسناد منطبق با عبارت متنی استفاده کنید. برای مرتب‌سازی نتایج به ترتیب نزولی امتیاز، $meta در عبارت مرتب‌سازی استفاده کنید. مثال‌های زیر را در نظر بگیرید، که در آن SCORE_FIELD نام فیلدی است که برای ذخیره مقدار امتیاز استفاده می‌شود:

  # Find query
  db.cities
    .find({ $text: { $search: "best french bread" } })
    .sort({ SCORE_FIELD: { $meta: "textScore" } })

  # Aggregation query
  db.cities.aggregate([
    { $match: { $text: { $search: "best french bread" } } },
    { $sort: { "SCORE_FIELD": { $meta: "textScore"} } },
  ]);

همچنین می‌توانید از امتیاز متن در عبارات پیش‌بینی استفاده کنید. برای مثال:

  # Find query
  db.cities
    .find({ $text: { $search: "best french bread" } })
    .project({ score: { $meta: "textScore" } })

  # Aggregation query
  db.cities.aggregate([
    { $match: { $text: { $search: "best french bread" } } },
    { $project: { "scoreField": { $meta: "textScore"} } },
  ]);

پرس و جو را گسترش دهید

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

محدودیت‌ها

  • عملگرهای $near و $text را نمی‌توان همزمان در یک کوئری استفاده کرد.
  • یک عملگر $text برای هر جستجوی find یا aggregation مجاز است.
  • در تجمیع‌ها، مرحله $match با $text باید اولین مرحله خط لوله باشد.
  • $text فقط می‌تواند درون $and ‎ و $or ‎ به صورت تو در تو تعریف شود.
  • اگر $text ‎ داخل $or ‎ باشد، ممکن است فصل‌های غیر جستجو از فهرست‌های مرتب موجود برای بهینه‌سازی پرس‌وجو استفاده کنند. اگر فصل‌های دیگر فهرست‌بندی نشده باشند، پرس‌وجو به یک اسکن مجموعه متکی خواهد بود.
  • نمی‌توان از $text به همراه query hints استفاده کرد.
  • کوئری‌هایی که جستجوی متنی دارند نمی‌توانند بر اساس $natural مرتب شوند.