چندی قبل پروژهای دولتی در زمینهی غلط یابی متون فارسی منتشر شد؛ اما ... آنچنان بازتابی در بین سایتهای ایرانی پیدا نکرد. حداکثر بازتاب آن مقالهی روزنامه همشهری در این حد بود که "مایکروسافت که یکی برامون درست کرده بود! تو چرا بی خود زحمت کشیدی!". البته روزنامهی همشهری هم مقصر نیست؛ چون به طور قطع نویسندهی آن با تواناییهای این برنامه در مقایسه با غلط یاب ساده مایکروسافت اطلاعات آنچنانی ندارد.
از سایتهای ایرانی هم نباید انتظار داشت که برای محصولات ایرانی تبلیغ کنند! اگر به سایتهای ایرانی فعال در زمینهی IT دقت کنید بیشتر ذوق کردنهای آنها ناشی از کارهای شرکت خارجی است؛ مثلا:
- گوگل امروز در صفحهی اولش یک عکس جدید گذاشته! (2000 تا سایت این رو پوشش میدن!)
- رئیس جدید مایکروسافت دیروز که میخواست بره سخنرانی دوبار جیغ کشید، سه بار دور سالن دوید گفت اینجا عجب شرکت باحالیه!
- استیوجابز خیلی مرد نازنینی است چون فقط یک دست شلوار لی و پولیور مشکی دارد که 10 سالش است همین فقط تنشه (هم... از شما چه پنهون وضع خود من هم بهتر از این نیست:) )
- فیس بوک امروز عکسهای شما رو در پروفایلتون هم نمایش میده!
وب سایتهای لینوکسی ایرانی هم که یک چیزی توی این مایهها هستند:
این مایکروسافت سه تا نقطه (!) باز یک سیستم عامل جدید بیرون داد، ولی اوبونتوی ما 5 ثانیه زودتر میاد بالا؛ به همین جهت هفته بعد قراره پس از طی مراحل نصب سیستم عامل که از امروز شروع میشه به همراه کلیه دوستانی که در این امر مهم دخیل هستند جشن بگیریم! زنده باد آزادی!
و ... سؤال اصلی اینجا است: چرا مدل توسعهای که از آن صحبت شد نمیفروشه؟! چرا کسی برای آن تبلیغ نکرد؟ چرا آنچنان کسی ذوق زده نشد؟! چرا زود فراموش شد؟
خوب؛ حالا بد نیست نگاهی هم داشته باشیم به مدل توسعهی "اونا"
یکی از این "اونا" مثلا میتونه تیم سیلورلایت مایکروسافت باشه. بیائیم ببینیم "اونا" چکار میکنند تا محصولاتشون بفروشه؛ ملت از شنیدن اخبار اونها ذوق زده بشن؛ هزارتا سایت کارشون رو به رایگان تبلیغ کنند و ...
- "اونا" یا کلا هر تیم توسعهای تشکیل شده از یک سری آدم! هر کدام از اینها یا در سایت MSDN یا به طور جداگانه وبلاگ دارند و کاری رو که به طور منظم انجام میدن، ارسال جزئیاتی اندک از پیشرفتهای حاصل شده است. مثلا آقای TimHeuer هر از چندگاهی این کار رو میکنه. به این صورت دیگه روزنامه همشهری چاپ نیویورک نمیاد بنویسه، Adobe که یکی برامون درست کرده بود! تو چرا بیخود زحمت کشیدی! چون الان روزنامهی نیویورک تایمز میدونه جزئیات کاری که انجام شده به مرور زمان چی بوده.
- "اونا" قسمتی رو در سایت MSDN دارند به نام Silverlight TV . یک نفر رو هم استخدام کردن به نام آقای جان پاپا! تا بیاد براشون با اعضای مختلف تیم مصاحبه کنه و یک سری از جزئیات رو بیشتر برای عموم مردم توضیح بده.
- "اونا" هر از چندگاهی سمینار برگزار میکنند: (+). میان پز میدن ما اینکار رو کردیم اونکار رو کردیم؛ دنیا، بدونید ما چقدر عالی هستیم!
- "اونا" یک bug tracking system دارند. یک features suggestion system دارند: (+) . مردم الان میدونند اگر باگی رو در سیستم پیدا کردند، کجا باید گزارش بدن. اگر نیاز به ویژگی جدیدی داشتند باید چکار کنند. صرفا با یک صفحهی ثابت که لینک دریافت دو تا فایل رو گذاشته مواجه نیستند.
- "اونا" یک فوروم مخصوص هم برای Silverlight درست کردند تا استفاده کنندهها بیان ابتداییترین تا پیشرفتهترین سوالات خودشون رو مطرح کنند. نرفتند اون پشت قایم بشن! یا بگن این ایمیل ما است؛ دوست داشتید ایمیل بزنید ما هم وقت کردیم جواب میدیم!
- "اونا" مستندات و راهنمای بسیار کامل، قوی و قابل مرور تحت وب دارند: (+).
- "اونا" اگر کارشون را رایگان و سورس باز میخواهند ارائه دهند از یک سورس کنترل استفاده میکنند: (+).به رها کردن یک تکه سورس کد در ملاء عام کار سورس باز نمیگن! هر کاری آداب و اصول خودش رو داره। شما که نمیای بچهت رو بذاری سر راه و بری؟! به این امید که خودش patch میشه، خودش به روز میشه، یکی پیدا میشه تا دستی به سرش بکشه!
البته این مورد جدیدا جهت پروژه غلط یاب یاد شده راه اندازی شده: (+) ولی فکر نمیکنم کسی متوجه شده باشه، چرا؟! چون اخبار رو این روزها علاقمندان از طریق فیدهای RSS دنبال میکنند؛ نه با مراجعهی هر روزه به یک سایت. انتظار بیموردی است که استفاده کنندگان هر روز به سایت ما سر بزنند تا ببینند چه خبره! به همین جهت RSS اختراع شده. همچنین پروژه اختصاصی فارسی و سورس کنترل انگلیسی هم همخوانی ندارند.
- "اونا" اکانت توئیتر دارند: (+). "اونا" اکانت فیس بوک دارند: (+). "اونا" از این امکانات برای گزارش دادن رخدادهای داخلی خودشون استفاده میکنند. یکی از ابزارهای مهم تبلیغاتی اونها است. کلا رسانهها رو در دنیای غرب به عصر قبل و بعد از توئیتر تقسیم بندی میکنند. پیش از توئیتر اخبار تهیه میشد و تبدیل به خوراک اطلاعاتی عموم میشد؛ الان اطلاعات موجود در توئیتر، جمع آوری، آنالیز و تحلیل میشود و سپس تبدیل به خوراک خبرگزاریها میگردد.
- "اونا" برای ارائه دانلودهاشون دیتاسنتر اختصاصی دارند. جایی خوندم مساحت دیتاسنترهای فعلی گوگل در حد یکی از ایالتهای آمریکا شده ...؛ تصورش رو بکنید که با یک وب سایت هاست شده در یک کشور ثالث، بخواهید یک نرم افزار 200 مگی را به هزاران نفر عرضه کنید. یا مشکل پنهای باند پیدا میکنید یا کند شدن سرور یا ...
- "اونا" اگر وقت کنند هر از چندگاهی برای تبلیغ و توسعه کارشون کتاب هم منتشر میکنند: (+)، تعدادی از اینها هم رایگان است.
و ... و ... بدون رعایت این موارد پروژههای خوب ارائه شده در اینترنت نمیفروشند! حتی شما دوست عزیز!
C# 6 - String Interpolation
using static System.FormattableString; var number = 11; var text = Invariant($"{number}");
آشنایی با NHibernate - قسمت ششم
برای مثال در قسمت هشتم یک سیستم many-to-many مثال زده شده است به همراه کوئریهایی از نوع Linq . اینجا فقط تعریف کلاسهایی که بیانگر روابط many-to-many باشند مهم است؛ نحوهی نگاشت خودکار آنها به دیتابیس کار Fluent NHibernate است. (از این نوع مثالها در هر قسمت پیاده سازی شده)
جزئیات ریز نحوهی نگاشت خودکار با مطالعهی سورس کتابخانه NHibernate و مشتقات آن قابل درک است (برای علاقمندان).
ضمنا فرقی نمیکند از Linq قسمت پنجم استفاده کنید یا هر روش موجود دیگری برای کوئری گرفتن (زمانیکه Linq هست و نگارشهای جدید آن برای NHibernate پیشرفت زیادی داشته، چرا روشهای دیگر؟).
https://github.com/MehdiSaeedifar/IrisStore
همچنین نمونهی آنلاین آنرا میتوانید در فروشگاه آیریس مشاهده کنید.
در ادامه برخی از قابلیتهای این سیستم را مشاهده میکنید:
جست و جو با قابلیت دسته بندی نتایج
به هنگام جست و جو، لیستی از موارد پیشنهادی به صورت دسته بندی شده نمایش داده میشود.
جست و جوی پیشرفته کالاها
جست و جو بر اساس قیمت، گروه، کلمات کلیدی و مرتب سازی نتایج انجام میگیرد. همچنین نتایج جست و جو بدون رفرش شدن صفحه و به صورت AJAX ای به همراه تغییر URL صفحه صورت میگیرد.
نمایش نمودار تغییرات قیمت
امکان نمایش نمودار تغییرات قیمت کالا در بازهی زمانی نیز پیش بینی شده است.
ویرایش اطلاعات به صورت inline
امکان ویرایش قیمت و تاریخ به صورت inline وجود دارد.
مدیریت تصاویر کالا
در این قسمت امکان آپلود همزمان چندین فایل به همراه پیش نمایش آنها وجود دارد. همچنین امکان کشیدن و رها کردن برای تغییر ترتیب چیدمان عکسها نیز مهیا است.( تصویر اول به عنوان کاور کالا در نظر گرفته میشود.)
قابلیتهای دیگر:
- مدیریت تصاویر اسلایدشو و تغییر ترتیب آنها از طریق کشیدن و رها کردن (drag & drop)
- تعریف برگه و تغییر ترتیب نمایش آنها از طریق کشیدن و رها کردن
- امکان ارسال پست
- تعریف دسته بندی
- مدیریت کاربران
- تعریف تنظیمات سایت
- نمایش کالا و پستهای مشابه
کارهایی که باید انجام شود:
- پیاده سازی سبد خرید و خرید آنلاین
تصویر پنل مدیریت
تصویر صفحهی اصلی:
همچنین به راحتی میتوان با طراحی قالب جدیدی، از این سیستم برای کاری غیر از فروشگاه اینترنتی استفاده کرد؛ سایتهای زیر نمونههای آنلاین دیگری از این سیستم هستند:
- http://www.petrapars.ir
- http://www.ava-tarh.ir
در نهایت فهرستی از کتاب خانهها و فناوریهای استفاده شده و همچنین مقالات مرتبط با این پروژه را قرار دادهام.
کتابخانهها و فریم ورکهای سمت سرور:
فناوری یا کتابخانه | توضیحات | مقالات مرتبط |
Bootstrap 3.x | فریم ورک پایه ای css سایت | - Bootstrap 3 RTL Theme - Twitter Bootstrap -سازگارسازی کلاسهای اعتبارسنجی Twitter Bootstrap 3 با فرمهای ASP.NET MVC -ساخت قالبهای نمایشی و ادیتور دکمه سه وضعیتی سازگار با Twitter bootstrap در ASP.NET MVC -نمایش اخطارها و پیامهای بوت استرپ به کمک TempData در ASP.NET MVC |
AdminLTE | قالب مدیریت سایت | - نسخه راستچین شده AdminLTE 2.2.1 |
Animate.css | انیمیشنهای css3 سایت | |
Font Awesome | پک آیکونهای برداری | |
Awesome Bootstrap Checkbox | زیبا سازی چک باکس ها | |
فونت فارسی وزیر | قلم فارسی | |
لطفا برای طرح سؤالات و پیشنهادات خود و جهت مدیریت بهتر آنها، از قسمت اختصاصی این پروژه در سایت استفاده نمائید.
فروشگاه IrisStore
https://github.com/MehdiSaeedifar/IrisStore
همچنین نمونهی آنلاین آنرا میتوانید در فروشگاه آیریس مشاهده کنید.
در ادامه برخی از قابلیتهای این سیستم را مشاهده میکنید:
جست و جو با قابلیت دسته بندی نتایج
به هنگام جست و جو، لیستی از موارد پیشنهادی به صورت دسته بندی شده نمایش داده میشود.
جست و جوی پیشرفته کالاها
جست و جو بر اساس قیمت، گروه، کلمات کلیدی و مرتب سازی نتایج انجام میگیرد. همچنین نتایج جست و جو بدون رفرش شدن صفحه و به صورت AJAX ای به همراه تغییر URL صفحه صورت میگیرد.
نمایش نمودار تغییرات قیمت
امکان نمایش نمودار تغییرات قیمت کالا در بازهی زمانی نیز پیش بینی شده است.
ویرایش اطلاعات به صورت inline
امکان ویرایش قیمت و تاریخ به صورت inline وجود دارد.
مدیریت تصاویر کالا
در این قسمت امکان آپلود همزمان چندین فایل به همراه پیش نمایش آنها وجود دارد. همچنین امکان کشیدن و رها کردن برای تغییر ترتیب چیدمان عکسها نیز مهیا است.( تصویر اول به عنوان کاور کالا در نظر گرفته میشود.)
قابلیتهای دیگر:
- مدیریت تصاویر اسلایدشو و تغییر ترتیب آنها از طریق کشیدن و رها کردن (drag & drop)
- تعریف برگه و تغییر ترتیب نمایش آنها از طریق کشیدن و رها کردن
- امکان ارسال پست
- تعریف دسته بندی
- مدیریت کاربران
- تعریف تنظیمات سایت
- نمایش کالا و پستهای مشابه
تصویر پنل مدیریت
تصویر صفحهی اصلی:
همچنین به راحتی میتوان با طراحی قالب جدیدی، از این سیستم برای کاری غیر از فروشگاه اینترنتی استفاده کرد؛ سایتهای زیر نمونههای آنلاین دیگری از این سیستم هستند:
- http://www.petrapars.ir
- http://www.ava-tarh.ir
در نهایت فهرستی از کتاب خانهها و فناوریهای استفاده شده و همچنین مقالات مرتبط با این پروژه را قرار دادهام.
کتابخانهها و فریم ورکهای سمت سرور:
فریمورکهای CSS:
فناوری یا کتابخانه | توضیحات | مقالات مرتبط |
Bootstrap 3.x | فریم ورک پایه ای css سایت | - Bootstrap 3 RTL Theme - Twitter Bootstrap -سازگارسازی کلاسهای اعتبارسنجی Twitter Bootstrap 3 با فرمهای ASP.NET MVC -ساخت قالبهای نمایشی و ادیتور دکمه سه وضعیتی سازگار با Twitter bootstrap در ASP.NET MVC -نمایش اخطارها و پیامهای بوت استرپ به کمک TempData در ASP.NET MVC |
AdminLTE | قالب مدیریت سایت | - نسخه راستچین شده AdminLTE 2.2.1 |
Animate.css | انیمیشنهای css3 سایت | |
Font Awesome | پک آیکونهای برداری | |
Awesome Bootstrap Checkbox | زیبا سازی چک باکس ها | |
فونت فارسی وزیر | قلم فارسی | |
var user = _documentSession .Include<User>(x => x.Apps[59].AddressId) .Load("Users/131-A"); var address = _documentSession.Load<Address>(user.Apps[59].AddressId)
var user = _documentSession .Include<User>(x => x.Apps.Values.Select(app => app.AddressId)) .Load("Users/131-A"); var addresses = List<Address>(); foreach(app in user.Apps) { addresses.Add(_documentSession.Load<Address>(app.AddressId)); //queryسمت کلاینت انجام اجرا میشود }
- حتما باید Id سند(ها) را داشته باشیم.
- کل سند را بازیابی میکند.
List<User> users = await _documentSession .Query<Users>() .Where(u => u.PhoneNumber.StartsWith("915")) .ToListAsync();
var users = await _documentSession.Query<AppUser>() .Where(u => u.Id.Equals("915")) .Select(u => new { u.Apps[appCode].FirstName, u.Apps [appCode].LastName, }) .ToListAsync();
from Users as user where startsWith(user.PhoneNumber, "915") select { FirstName : user.Apps ["59"].FirstName, LastName : user.Apps ["59"].LastName }
from u in _documentSession.Query<User>() where u.PhoneNumber.StartsWith("915") let app = u.Apps["59"] select new { app.FirstName, app.LastName, };
declare function output(u) { var app = u.Apps["59"]; return { FirstName : app.FirstName, LastName : app.LastName}; } from Users as user where startsWith(user.PhoneNumber, "915") select output(user)
app.FirstName, app.LastName, *key = u.ActiveInApps.Select(a => a.Key)
query = query.Search(u => u.key, "59");
public class User_MyIndex : AbstractIndexCreationTask<User> { Map = users => from u in users from app in u.Apps select new { Id = u.Id, PhoneNumber = u.PhoneNumber, UserName = app.Value.UserName, FirstName = app.Value.FirstName, LastName = app.Value.LastName, IsActive = app.Value.IsActive, key = app.Key }; }
new User_MyIndex().Execute(store);
IndexCreation.CreateIndexes(typeof(User_MyIndex).Assembly, store);
from u in _documentSession.Query<User, User_MyIndex>() ...
select new { ... key = aia.Key, Address = LoadDocument<Address>(aia.Value.AddressId), // City = LoadDocument<Address>(aia.Value.AddressId).City, };
Message = app.Messages.Select(m => LoadDocument<Message>(m).Content)
var users = _documentSession.Advanced.AsyncDocumentQuery<User, User_MyIndex>() .WhereStartsWith(nameof(AppUser.PhoneNumber), "915") .WhereEquals("key", appCode, exact: true) .SelectFields<AppUserModel>(new[] { $"Apps[{appCode}].FirstName", $"Apps[{appCode}].LastName" }) .ToListAsync();
public class Post { public int Id { get; set; } public string Content { get; set; } public string Title { get; set; } public List<string> Tags { get; set; } public string WriterName { get; set; } public string WriterId { get; set; } }
public class Post_ByContent : AbstractIndexCreationTask<Post> { public Post_ByContent() { Map = posts=> from post in posts select new { post.Content }; Analyzers.Add(p => p.Content, "StandardAnalyzer"); } }
List<Post> posts = _documentSession .Query<Post, Post_ByContent>() .MoreLikeThis(builder => builder .UsingDocument(p => p.Id == "posts/59-A") .WithOptions(new MoreLikeThisOptions { Fields = new[] { nameof(Post.Content) }, StopWordsDocumentId = "appConfig/StopWords" })) .ToList();
پیاده سازی ویژگی Health Check بدون استفاده از قابلیتهای ASP.NET Core 2.2
اگر بخواهیم در بررسی سلامت برنامه، وضعیت بانک اطلاعاتی آنرا گزارش دهیم، میتوان یک چنین اکشن متدی را طراحی کرد که در آن اتصالی به بانک اطلاعاتی باز شده و اگر در حین فراخوانی مسیر working/، استثنائی رخ داد، با بازگشت status code مساوی 503، عدم سلامت برنامه اعلام شود؛ کاری که سرویسهای ping متداول نمیتوانند آنرا با این دقت انجام دهند:
[Route("working")] public ActionResult Working() { using (var connection = new SqlConnection(_connectionString)) { try { connection.Open(); } catch (SqlException) { return new HttpStatusCodeResult(503, "Generic error"); } } return new EmptyResult(); }
بازنویسی قطعه کد فوق با ویژگی جدید Health Check در ASP.NET Core 2.2
اکنون اگر بخواهیم قطعه کد فوق را با کمک ویژگیهای جدید ASP.NET Core 2.2 بازنویسی کنیم، روش کار به صورت زیر خواهد بود:
namespace MvcHealthCheckTest { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddHealthChecks() .AddCheck("sql", () => { using (var connection = new SqlConnection(Configuration["connectionString"])) { try { connection.Open(); } catch (SqlException) { return HealthCheckResult.Unhealthy(); } } return HealthCheckResult.Healthy(); }); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseHealthChecks("/working");
- سپس توسط متد app.UseHealthChecks، بدون اینکه نیاز باشد کنترلر و اکشن متد جدیدی را جهت بازگشت وضعیت سلامت برنامه، تعریف کنیم، مسیر working/ قابل دسترسی خواهد شد.
تا اینجا اگر این مسیر را به سرویس بررسی uptime برنامهی خود معرفی کنید، صرفا وضعیت قابل دسترسی بودن مسیر working/ را دریافت خواهید کرد. اگر نیاز به گزارش دقیقتری وجود داشت، میتوان به کمک متد AddCheck، یک منطق سفارشی را نیز به آن افزود؛ همانند بررسی امکان اتصال به بانک اطلاعاتی، به روشی که ملاحظه میکنید. در اینجا اگر منطق مدنظر با موفقیت اجرا شد، HealthCheckResult.Healthy بازگشت داده میشود و یا HealthCheckResult.Unhealthy در صورت عدم موفقیت. هر کدام از این متدها میتوانند توضیحات و یا اطلاعات بیشتری را نیز توسط پارامترهای خود ارائه دهند.
امکان تهیه سرویسهای سفارشی بررسی سلامت برنامه
در مثال قبل، منطق بررسی سلامت برنامه را همانجا داخل متد ConfigureServices، به کمک متد services.AddHealthChecks().AddCheck معرفی کردیم. امکان انتقال این کدها به سرویسهای سفارشی، با پیاده سازی اینترفیس IHealthCheck نیز وجود دارد:
public class SqlServerHealthCheck : IHealthCheck { private readonly IConfiguration _configuration; public SqlServerHealthCheck(IConfiguration configuration) { _configuration = configuration; } public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken)) { using (var connection = new SqlConnection(_configuration["connectionString"])) { try { connection.Open(); } catch (SqlException) { return Task.FromResult(HealthCheckResult.Unhealthy()); } } return Task.FromResult(HealthCheckResult.Healthy()); } }
namespace MvcHealthCheckTest { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddHealthChecks() .AddCheck<SqlServerHealthCheck>("sql");
سفارشی سازی خروجی بررسی سلامت برنامهها
تا اینجا از متدهای کلی Unhealthy و Healthy برای بازگشت وضعیت سلامت برنامه استفاده کردیم؛ خروجیهای بهتری را نیز میتوان ارائه داد:
public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken)) { using (var connection = new SqlConnection(_configuration["connectionString"])) { try { connection.Open(); } catch (SqlException) { return Task.FromResult(new HealthCheckResult( status: context.Registration.FailureStatus, description: "It is dead!")); } } return Task.FromResult(HealthCheckResult.Healthy("Healthy as a horse")); }
روش دیگر سفارشی سازی خروجی آن، استفاده از پارامتر دوم متد app.UseHealthChecks است:
namespace MvcHealthCheckTest { public class Startup { public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseHealthChecks("/working", new HealthCheckOptions { ResponseWriter = async (context, report) => { var result = JsonConvert.SerializeObject(new { status = report.Status.ToString(), errors = report.Entries.Select(e => new { key = e.Key, value = Enum.GetName(typeof(HealthStatus), e.Value.Status) }) }); context.Response.ContentType = MediaTypeNames.Application.Json; await context.Response.WriteAsync(result); } });
معرفی کتابخانهای از IHealthCheckهای سفارشی
از مخزن کد AspNetCore.Diagnostics.HealthChecks میتوانید IHealthCheckهای سفارشی مخصوص SQL Server، MySQL و غیره را نیز دریافت و استفاده کنید.
نگاهی به محتوا و نحوهی تشکیل ایندکسهای FTS
متد sys.dm_fts_index_keywords
این متد محتوای full-text index یک جدول را باز میگرداند. از آن میتوان برای موارد ذیل استفاده کرد:
- آیا واژه کلیدی خاصی جزو full-text index است؟
- چه تعداد رکورد دارای واژهی کلیدی خاصی هستند؟
- متداولترین واژههای کلیدی موجود در ایندکس کدامند؟
- کدام واژه را میتوان به عنوان stop word تشخیص داد؟ شاید پس از بررسی، تشخیص داده شود که بهتر است متداولترین واژهی کلیدی ایندکس شده، به stop list اضافه شود.
SELECT * FROM sys.dm_fts_index_keywords(DB_ID(DB_NAME()), OBJECT_ID(N'dbo.Documents'));
متد sys.dm_fts_index_keywords_by_document
این متد اطلاعاتی را در سطح اسناد باز میگرداند. کاربردهای آن میتوانند شامل موارد زیر باشند:
- یافتن جمع تعداد واژههای کلیدی که یک full-text index دارا است.
- آیا واژهی کلیدی مورد نظر، در ردیف در حال بررسی وجود دارد؟
- یک واژهی کلیدی چندبار در کل ایندکس ظاهر شدهاست؟
- یک واژهی کلیدی در یک ردیف یا سند مشخص، چندبار تکرار شدهاست؟
- یک ردیف یا سند، از چند واژهی کلیدی تشکیل شدهاست؟
SELECT I.document_id, D.title, I.display_term, I.occurrence_count FROM sys.dm_fts_index_keywords_by_document(DB_ID(DB_NAME()), OBJECT_ID(N'dbo.Documents')) AS I INNER JOIN dbo.Documents D ON D.id = I.document_id;
متد sys.dm_fts_index_keywords_by_property
در قسمتهای قبل، خواص و متادیتای اسناد آفیس را نیز ایندکس کردیم. این متد، اطلاعات مرتبط با خواص اسناد موجود در full-text index را باز میگرداند.
کاربردهای آن:
- چه محتوایی، در خاصیتی مشخص از سندی معلوم، ذخیره شدهاست؟
- خاصیت مورد نظر چه اندازه بکار رفته و تکرار شدهاست؟
- چه اسنادی دارای خاصیتی مشخص هستند؟
SELECT I.document_id, D.title, I.display_term, I.property_id FROM sys.dm_fts_index_keywords_by_property(DB_ID(DB_NAME()), OBJECT_ID(N'dbo.Documents')) AS I INNER JOIN dbo.Documents D ON D.id = I.document_id;
متد sys.dm_fts_parser
متدهای قبلی که بررسی کردیم، نیاز به یک جدول و وجود full-text index بر روی آن دارند؛ اما متد dm_fts_parser خیر. این متد یک ورودی را گرفته و سپس تمام مراحل تهیهی یک full-text index را به صورت پویا انجام میدهد.
کاربردهای آن:
- درک اینکه موتور FTS با یک ورودی رشتهای چگونه رفتار میکند.
- استخراج ایندکسهای یک متن و ذخیرهی دستی آن در یک جدول.
- استخراج واژههای کلیدی یک رشته.
- آنالیز پویای INFLECTIONAL (مانند مثال زیر)
SELECT display_term, keyword FROM sys.dm_fts_parser(N'"Mycustom string"', 1033, NULL, 0);
SELECT * FROM sys.dm_fts_parser('FORMSOF(INFLECTIONAL,'+ 'term' + ')', 1033, NULL, 0);
در اینجا پارامتر دوم آن شماره زبان مورد استفاده است. پارامتر سوم مشخص کنندهی stop list میتواند باشد و پارامتر سوم حساسیت به لهجه را مشخص میکند.