raha_hakhamanesh
شنبه 05 اسفند 1391, 13:15 عصر
با سلام خدمت اساتید بزرگوار
من در یک پروژه متن کاوی با مشکل جستجو و رتبه بندی در دیتابیس مواجه هستم لطفا در این خصوص نظرات و راهنمایی های خودتان را دریغ نفرمایید.
یک بانک اطاعاتی با دو میلیون رکورد داریم که هر رکورد محتوای یک ایمیل است. برای دسته بندی باید به دنبال کلمات کلیدی مورد نظر در این ایمیل ها بگردیم و بر اساس تعداد تکرارشان، رکوردها را وزن دهی یا اولویت گذاری کنیم، نهایتا رکوردهای با بیشترین تکرار در اولویت نمایش قرار گیرند.
کاری که من انجام داده ام
ابتدا همه رکوردهایی را که شامل کلمه کلیدی هستند از دیتابیس فراخوانی کردم:
StrCmd = " SELECT [EmID],[Sub],[Body] FROM Tbl_Source WHERE ( ";
StrCmd += " Sub LIKE '%" + word1 + "%' OR Body LIKE '%" + word1 + "%' ";
StrCmd += " Sub LIKE '%" + word2 + "%' OR Body LIKE '%" + word2 + "%') ";
تا اینجای کار بد نیست، سپس رکوردهایی که با دستور فوق انتخاب شدن را یکی یکی به تابع Search ارسال می کنم تا تعداد حضور کلمات مورد نظرمان را بشمارد:
dr = Cmd.ExecuteReader();
while (dr.Read())
{
EID = dr["EID"].ToString();
Subject = dr["Sub"].ToString();
Body = dr["Body"].ToString();
ret_Rate = Search(EID, Subject, Body);
UpdateRecord(EID, ret_Rate);
}
dr.Close();
تابع جستجو هم به شرح زیر است:
[1] Rate = 0;
[2] for (int i = 0; i < word.Length; i++)
[3] if (words[i].Length > 0)
{
//============================== find how many occurrence in subject
[4] Subject = Subject.ToLower();
[5] Rate += new Regex(words[i]).Matches(Subject).Count * 2;
//============================== find how many occurrence in Body
[6] Body = Body.ToLower();
[7] Rate += new Regex(words[i]).Matches(Body).Count;
}
که در کد فوق، خط 7 تعداد کلمات (words[i]) موجود در فیلد Body رو بر می گردونه، در خط 4 هم بطور مشابه؛ با این تفاوت که در یک عدد 2 ضرب میشه تا وزن بیشتری از خودش نشون بده و دلیلش هم اینه که کلمه مربوطه در عنوان ایمیل است که برای ما مهمتر می باشد.
اما اشکال کار»
بعد از تحلیل برنامه، متوجه شدم برای یک تحلیل بر روی 500 هزار رکورد برنامه ما، یک ثانیه زمان می خواد تا اطلاعات رو از دیتابیس Fetch کنه (کد اول)، ولی 147 ثانیه طول میکشه تا رکوردها رو یکی یکی به تابع Search بفرسته و تعداد تکرار کلمات (رتبه اون رکورد) را محاسبه کند!
متاسفانه این زمان قابل قبول نیست و نمی تونیم با اون کار کنیم
چیزی که بنظرم می رسه این است که قطعه کد دوم که هر رکورد را یکی یکی از طریق DataReader برای ارزیابی به تابع Search می فرسته بهینه نیست!؟ (البته مطمئن نیستم) و شاید بتوان در دستورات SQL این را جایگزین کنیم!
منتظر نظرات و راهنمایی های شما عزیزان هستم
(هر نکته ای ممکن است گره ای از این مشکل را باز کند، بسم الله)
من در یک پروژه متن کاوی با مشکل جستجو و رتبه بندی در دیتابیس مواجه هستم لطفا در این خصوص نظرات و راهنمایی های خودتان را دریغ نفرمایید.
یک بانک اطاعاتی با دو میلیون رکورد داریم که هر رکورد محتوای یک ایمیل است. برای دسته بندی باید به دنبال کلمات کلیدی مورد نظر در این ایمیل ها بگردیم و بر اساس تعداد تکرارشان، رکوردها را وزن دهی یا اولویت گذاری کنیم، نهایتا رکوردهای با بیشترین تکرار در اولویت نمایش قرار گیرند.
کاری که من انجام داده ام
ابتدا همه رکوردهایی را که شامل کلمه کلیدی هستند از دیتابیس فراخوانی کردم:
StrCmd = " SELECT [EmID],[Sub],[Body] FROM Tbl_Source WHERE ( ";
StrCmd += " Sub LIKE '%" + word1 + "%' OR Body LIKE '%" + word1 + "%' ";
StrCmd += " Sub LIKE '%" + word2 + "%' OR Body LIKE '%" + word2 + "%') ";
تا اینجای کار بد نیست، سپس رکوردهایی که با دستور فوق انتخاب شدن را یکی یکی به تابع Search ارسال می کنم تا تعداد حضور کلمات مورد نظرمان را بشمارد:
dr = Cmd.ExecuteReader();
while (dr.Read())
{
EID = dr["EID"].ToString();
Subject = dr["Sub"].ToString();
Body = dr["Body"].ToString();
ret_Rate = Search(EID, Subject, Body);
UpdateRecord(EID, ret_Rate);
}
dr.Close();
تابع جستجو هم به شرح زیر است:
[1] Rate = 0;
[2] for (int i = 0; i < word.Length; i++)
[3] if (words[i].Length > 0)
{
//============================== find how many occurrence in subject
[4] Subject = Subject.ToLower();
[5] Rate += new Regex(words[i]).Matches(Subject).Count * 2;
//============================== find how many occurrence in Body
[6] Body = Body.ToLower();
[7] Rate += new Regex(words[i]).Matches(Body).Count;
}
که در کد فوق، خط 7 تعداد کلمات (words[i]) موجود در فیلد Body رو بر می گردونه، در خط 4 هم بطور مشابه؛ با این تفاوت که در یک عدد 2 ضرب میشه تا وزن بیشتری از خودش نشون بده و دلیلش هم اینه که کلمه مربوطه در عنوان ایمیل است که برای ما مهمتر می باشد.
اما اشکال کار»
بعد از تحلیل برنامه، متوجه شدم برای یک تحلیل بر روی 500 هزار رکورد برنامه ما، یک ثانیه زمان می خواد تا اطلاعات رو از دیتابیس Fetch کنه (کد اول)، ولی 147 ثانیه طول میکشه تا رکوردها رو یکی یکی به تابع Search بفرسته و تعداد تکرار کلمات (رتبه اون رکورد) را محاسبه کند!
متاسفانه این زمان قابل قبول نیست و نمی تونیم با اون کار کنیم
چیزی که بنظرم می رسه این است که قطعه کد دوم که هر رکورد را یکی یکی از طریق DataReader برای ارزیابی به تابع Search می فرسته بهینه نیست!؟ (البته مطمئن نیستم) و شاید بتوان در دستورات SQL این را جایگزین کنیم!
منتظر نظرات و راهنمایی های شما عزیزان هستم
(هر نکته ای ممکن است گره ای از این مشکل را باز کند، بسم الله)