لوسین در MVC

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

امکانات بالای این کتابخانه آن را به یکی از بهترین کتابخانه های دات نت در این زمینه خودش تبدیل کرده است.

همچنین سرعت زیاد این کتابخانه به دلیل ایندکس گذاری مطالب و امکانات کامل آن یکی از دلایل محبوبیتش می باشد و روز به روز در حال تکمیل شدن می باشد.

در ادامه با امکانات لوسین در MVC اشنا میشوید همراه ما باشید.

  1. AutoComplete
  2.  غلط گیر املایی
  3. انجام محاسبات آماری بر روی متون
  4. امکان یافتن مطالبی مشابه
  5. Highlight کردن عبارت مورد جستجو

می باشد که برای دات نت نیز امکان استفاده آن فراهم شده است.

موتور لوسین امکان جستجوی سریع رو مطالب حجیم، بوسیله ایندکس گذاری فراهم می آورد .

ابتدا باید از طریق آدرس زیر ۲ کتابخانه لازم را دریافت و نصب نمایید:

وارد منوی Tools شوید سپس NuGet Package Manager و Manage NuGet Package For Solution را انتخاب کنید.

قسمت online را انتخاب کنید و سپس کلمه Lucene.NET را جستجو کنید و آن را نصب کنید.

سپس کتابخانه Lucene.Net Contrib را نیز نصب کنید.

کتابخانه Lucene مستقل از منبع داده است و تنها اطلاعاتی با فرمت شیء Document معرفی شده به آن‌ را می‌شناسد.

پس باید ابتدا هر رکورد از اطلاعات خود را به شیء Document تبدیل کنیم.

لوسین برای انجام این عمل از متد زیر استفاده میکند:


static Document MapPostToDocument(Products post)
{
var postDocument = new Document();

postDocument.Add(new Field("ProductID", post.ProductID.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
var ProductName =
new Field("ProductName", post.ProductName, Field.Store.YES, Field.Index.ANALYZED,
Field.TermVector.WITH_POSITIONS_OFFSETS);
ProductName.Boost = 3;
postDocument.Add(ProductName);
return postDocument;
}

این متد یک شی Products دریافت میکند و آنرا تبدیل به سند لوسین می کند.

ابتدا به کلاس Field نام فیلد مورد نظر را میدهیم سپس مقدار متناظر(دقت کنید که مقدار متناظر باید به صورت رشته باشد)

نکته مهم در آرگومان سوم می باشد Field.Store.YES به این معنی می باشد که اصل اطلاعات نیز علاوه بر ایندکس شدن در فایل های لوسین ذخیره شود زمانی از Yes استفاده میکنیم ،که میخواهیم اطلاعاتی را به کاربر نمایش دهیم .

در غیر اینصورت از Field.Store.No استفاده میکنیم.

توسط Boost به لوسین خواهیم گفت که اهمیت عبارات ذکر شده در عناوین مطالب، بیشتر است از اهمیت متون آن‌ها است.

در آرگومان چهارم مشخص میکنیم که اطلاعات فیلد مورد نظر ایندکس شوند یا خیر.

چون روی ProductID جستجو صورت نمیگیرد از Field.Index.NOT_ANALYZED استفاده میکنیم.

حال برای Highlighte کردن عبارت مورد جستجو باید از آرگومان Field.TermVector.WITH_POSITIONS_OFFSETS استفاده کرد.

حالا باید اطلاعاتی را که به اسناد لوسین تبدیل کردیم به فایل های Full text search لوسین تبدیل کنیم برای این کار از متد زیر استفاده میکنیم:



static readonly Lucene.Net.Util.Version _version = Lucene.Net.Util.Version.LUCENE_30;
public static void CreateIdx(IEnumerableProducts dataList)
{
var directory = FSDirectory.Open(new DirectoryInfo(HttpRuntime.AppDomainAppPath + @"App_Data\LuceneIndex"));
var analyzer = new StandardAnalyzer(_version);
using (var writer = new IndexWriter(directory, analyzer, create: true, mfl: IndexWriter.MaxFieldLength.UNLIMITED))
{
foreach (var post in dataList)
{
writer.AddDocument(MapPostToDocument(post));
}

writer.Optimize();
writer.Commit();
writer.Dispose();
directory.Dispose();
}
}

ابتدا محل ذخیره سازی فایل‌های full text search را مشخص میکنیم.

در اینجا من مسیر رو به شکلی قرار دادم که در داخل پروژه درون پوشه App_Data یک پوشه با نام LuceneIndex بسازد و داخل آن فایل های خود را کپی کند.

لوسین برای انجام ادامه کار خود نیاز به یک آنالیز کننده اطلاعات نیاز دارد که ازکلاس StandardAnalyzer لوسین استفاده میکنیم.

اسناد لوسین را به شی indexWriter اضافه میکنیم.

دلیل ذکر ورژن این است که ایندکس ها با نگارش بعدی سازگار باشند.

شما باید دو نکته مهم را در کد های خود رعایت کنید:

  1. بروزرسانی ایندکس ها می باشد
  2. محل قرار گیری متد های انجام این کار (باید در کنار متدهای به روز رسانی اطلاعات اصلی در بانک اطلاعاتی برنامه به کار برده شود)

لوسین برای انجام این کار از۳ متد زیر استفاده می کند:


public static void UpdateIndex(Products post)
{
var directory = FSDirectory.Open(new DirectoryInfo(HttpRuntime.AppDomainAppPath + @"App_Data\LuceneIndex"));
var analyzer = new StandardAnalyzer(_version);
using (var indexWriter = new IndexWriter(directory, analyzer, create: false, mfl: IndexWriter.MaxFieldLength.UNLIMITED))
{
var newDoc = MapPostToDocument(post);

indexWriter.UpdateDocument(new Term("ProductID", post.ProductID.ToString()), newDoc);
indexWriter.Commit();
indexWriter.Dispose();
directory.Dispose();
}
}

public static void DeleteIndex(Products post)
{
var directory = FSDirectory.Open(new DirectoryInfo(HttpRuntime.AppDomainAppPath + @"App_Data\LuceneIndex"));
var analyzer = new StandardAnalyzer(_version);
using (var indexWriter = new IndexWriter(directory, analyzer, create: false, mfl: IndexWriter.MaxFieldLength.UNLIMITED))
{
indexWriter.DeleteDocuments(new Term("ProductID", post.ProductID.ToString()));
indexWriter.Commit();
indexWriter.Dispose();
directory.Dispose();
}
}

public static void AddIndex(Products post)
{
var directory = FSDirectory.Open(new DirectoryInfo(HttpRuntime.AppDomainAppPath + @"App_Data\LuceneIndex"));
var analyzer = new StandardAnalyzer(_version);
using (var indexWriter = new IndexWriter(directory, analyzer, create: false, mfl: IndexWriter.MaxFieldLength.UNLIMITED))
{
var searchQuery = new TermQuery(new Term("ProductID", post.ProductID.ToString()));
indexWriter.DeleteDocuments(searchQuery);

var newDoc = MapPostToDocument(post);
indexWriter.AddDocument(newDoc);
indexWriter.Commit();
indexWriter.Dispose();
directory.Dispose();
}
}

حال برای اجرای AutoComplete یک کلاس به برنامه خود اضافه میکنیم و کدهای زیر را به آن اضافه میکنیم:


public static class AutoComplete
{
private static IndexSearcher _searcher;

///summary
/// Get terms starting with the given prefix
////summary
///param name="prefix"/param
///param name="maxItems"/param
///returns/returns
public static IListProducts GetTermsScored(string indexPath, string prefix, int maxItems = 10)
{
if (_searcher == null)
_searcher = new IndexSearcher(FSDirectory.Open(new DirectoryInfo(indexPath)), true);

var resultsList = new ListProducts();
if (string.IsNullOrWhiteSpace(prefix))
return resultsList;

prefix = prefix.ApplyCorrectYeKe();

var results = _searcher.Search(new PrefixQuery(new Term("ProductName", prefix)), null, maxItems);
foreach (var doc in results.ScoreDocs)
{
resultsList.Add(new Products
{
ProductName = _searcher.Doc(doc.Doc).Get("ProductName"),
ProductID = int.Parse(_searcher.Doc(doc.Doc).Get("ProductID"))
});
}

return resultsList;
}
}

در این قسمت توسط PrefixQuery به تعدادی که خودمان تعیین میکنیم (توسط maxItems در ورودی تابع GetTermsScored ) رکورد های یافت شده را بازگشت خواهیم داد.
خروجی لیستی است از SearchResultها شامل عنوان مطلب و Id آن که عنوان را به کاربر نمایش خواهیم دادو از Id برای هدایت اواستفاده خواهیم کرد.

حال در کنترلر خود قبل از تابع index کد زیر را بنویسید:


static string _indexPath = HttpRuntime.AppDomainAppPath + @"App_Data\LuceneIndex";

کد بالا مسیر فایل های ایندکس شده می باشد.

برای نمایش از کد زیر استفاده میکنیم :

public ActionResult ScoredTerms(string q)
{
if (string.IsNullOrWhiteSpace(q))
return Content(string.Empty);

var result = new StringBuilder();
var items = AutoComplete.GetTermsScored(_indexPath, q);
foreach (var item in items)
{
var postUrl = this.Url.Action(actionName: Index, controllerName: Home, routeValues: new { id = item.ProductID }, protocol: http);
result.AppendLine(item.ProductName + | + postUrl);
}

return Content(result.ToString());
}

ابتدا ارجاعاتی را به jQuery، افزونه Auto-Complete و اسکریپت سفارشی تهیه شده، در فایل layout پروژه تعریف خواهیم کرد.

script src=~/Scripts/jquery-1.7.1.min.jstype=text/javascript/script
script src=~/Scripts/jquery.autocomplete.jstype=text/javascript/script
script src=~/Scripts/custom.jstype=text/javascript/script

به ویو خود رفته وبه ویو را به شکل زیر تغییر دهید:

@{
ViewBag.Title = جستجو;
var scoredTermsUrl = Url.Action(actionName: ScoredTerms, controllerName: Home);
var bulletImage = Url.Content(~/Content/Images/bullet_shape.png);
}
h2
جستجو
/h2

div align=center
@Html.TextBox(term, , htmlAttributes: new { dir = ltr })
br /
جهت آزمایش او را وارد نمائید
/div

@section scripts
{
script type=text/javascript
EnableSearchAutocomplete('@scoredTermsUrl', '@bulletImage');
/script
}

قسمت مهم کدهای کنترلر :

result.AppendLine(item.Title + | + postUrl);
return Content(result.ToString());

توضیحات لازم:

مطابق نیاز افزونه انتخاب شده در مثال جاری، فرمت خروجی مدنظر باید شامل سطرهایی حاوی متن قابل نمایش باشد.

return Content هم سبب بازگشت این اطلاعات به افزونه خواهد شد.

نکات مهم :

بدنه متد EnableSearchAutocomplete در custom.js قر دارد تنظیم آن به اینصورت است که بعد از تایپ ۲ کاراکتر شروع به جستجو میکند برای تغییر آن میتوانید minChars:2 عدد دلخواه را وارد کنید.

نام textbox دارای اهمیت می باشد به دلیل استفاده در متد جاوا اسکریپتی EnableSearchAutocomplete

نحوه مقدار دهی آدرس دسترسی به اکشن متد ScoredTerms نیز مهم می‌باشد.

توضیحات اسکریپت:

  • در متد EnableSearchAutocomplete نحوه فراخوانی افزونه autocomplete را ملاحظه می‌کنید.

جهت آن، به راست به چپ تنظیم شده است.

با ۲ کاراکتر ورودی فعال خواهد شد با وقفه‌ای کوتاه.

نیازی نیست تا انتخاب کاربر از لیست ظاهر شده حتما با عبارت جستجو شده صد در صد یکی باشد.

حداکثر ۲۰ آیتم در لیست ظاهر خواهند شد.

اسکرول بار لیست را حذف کرده‌ایم. عرض آن به ۳۰۰ تنظیم شده است و نحوه فرمت دهی نمایشی آن‌را نیز ملاحظه می‌کنید.

برای این منظور از متد formatItem استفاده شده است.

آرایه row در اینجا در برگیرنده اعضای Title و Id ارسالی به افزونه است.

اندیس صفر آن به عنوان دریافتی اشاره می‌کند.

همچنین نحوه نشان دادن عکس العمل به عنصر انتخابی را هم ملاحظه می‌کنید (در متد result مقدار دهی شده).

window.location را به عنصر دوم آرایه row هدایت خواهیم کرد.

این عنصر دوم مطابق کدهای اکشن متد تهیه شده، به آدرس یک صفحه اشاره می‌کند.

جزئیات فایل

زبان پروژه : C#&MVC

دانلود فایل

دانلود با لینک مستقیم
پسورد فایل : www.mspsoft.com
پاکان رحمانی

نوشته‌های مرتبط

دیدگاه‌ها

*
*

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

    سعيد پاسخ

    دوست عزيز؛ خوب ماخذ مطلب رو هم مي‌نوشتيد كه از كدام سايت ايراني تهيه شده.

      پاکان رحمانی پاسخ

      از یک سایت نیست و از منابع ایرانی و خارجی مورد مطالعه قرار گرفته و سعی شده خیلی کاربردی و قابل فهم ارائه شود تا همه دوستان بتوانند استفاده کنند وبرای راهنمایی شما دوست عزیز مطالب کاملتر و امکانات دیگر این کتابخانه در سایت www.dotnettips.info توضیح داده شده است

    Mahdi پاسخ

    ممنون جناب رحمانی از آموزش کاملتون ممنونم.عالی بود

    مهدی پاسخ

    با سلام،

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

    موفق باشید.