All blog posts of month 12 of the year 2011

חיפוש עברי בספריה הלאומית

HebMorph, Hebrew posts | עברית, IR Comments (0)

"כל מאגרי הספריה הלאומית, עכשיו באינטרנט", זעקו הכותרות. כחובב טקסטים, הלכתי לראות על מה מדובר.

באתר הספריה (http://web.nli.org.il) יש גישה לקטלוג ולארכיונים שונים, כאשר בראש האתר עומדת תיבת טקסט לחיפוש חופשי. כמובן שזה הדבר הראשון שניסיתי באתר...

ובכן, עושה רושם שבעיית החיפוש העברי אכן היתה ידועה ונלקחה בחשבון בבניית האתר. נראה שאיזו שהיא תשומת לב אכן ניתנה לטיפול מורפולוגי כלשהו, אך חבל שהתוצאות רחוקות מלהיות טובות, ואפילו נכונות.

כמה דוגמאות מייצגות ומסקנותיהן (בקצרה) בצידן:

  1. חיפוש עבור "רבין" מביא תוצאות לא רלוונטיות כלל ב-6 התוצאות הראשונות (עם המילה "רביניו" מודגשת). הקלטת שמע מאת עוזר רבין מופיעה שביעית, ראשונה מבין התוצאות עבור "רבין". זהו recall גרוע במיוחד. הסיבה לכך היא מתן משקל זהה לצורות מדויקות וצורות החשודות כדומות, וכדאי לשים לב שמדובר על מילה בעלת הטיות אפשריות מעטות מאד.
  2. אותיות מש"ה וכל"ב כלל לא מטופלות כראוי - חיפוש עבור "הלב" לא מחזיר תוצאות בהן מופיעה המילה "לב", ומאוחזרות רק הטיות של המילה "לב" עם התחילית ה'. זו אינה הדרך הנכונה הנכונה לבצע זאת - נרצה לדרג אחזורים מדוייקים גבוה יותר, אך לא לאבד אחזורים רלוונטיים שנכתבו במקור ללא אותיות מש"ה וכל"ב.
  3. גרשיים. לא נתמכים. בכלל. חיפוש עבור צה"ל, רמב"ם, רמב"ן לא מניב אף תוצאה (אבל צהל, רמבם כן).
  4. כתיב מלא / חסר - לא נתמך כלל. חיפושים עבור אמא / אימא, חנוכיה / חנוכייה, ספריה / ספרייה ועוד מחזירים תוצאות שונות לחלוטין.
כל הדוגמאות הנ"ל גורמות לי להאמין שמדובר על query expansion מסוג כלשהו, ובכל אופן ברור שמדובר על מנוע חיפוש קליל ביותר עבור מאגר הספרים הלאומי. החיפוש אינו ממצה, ובעל precision & recall נמוכים ביותר. בכמה הרצאות שנתתי בנושא כבר הראיתי דוגמאות לכך באתרים כמו ווינט, ויקיפדיה העברית ותפוז, אך דווקא מהספריה הלאומית ציפיתי ליותר... פרוייקט HebMorph, עליו ניתן לקרוא הרבה גם באתר זה, נועד בדיוק למטרה זו, והוא בקוד פתוח (עם אופציה לשימוש מסחרי). בשימוש קצר ב-demo החי ניתן להתרשם מכך שהמנוע כבר מטפל גם בנקודות שאוזכרו...

RavenDB Caching done right (EventsZilla part II)

.NET, English posts, EventsZilla, RavenDB Comments (1)

In the previous post we created the basics for an events publishing application, and discussed the modeling aspect of things.

I put some more work into the app, and now it actually works and looks pretty nice. Queries and loads are in place for the front-end, so it is time to visit one key feature of RavenDB - Caching.

Basic caching

The RavenDB Client API provides automatic out-of-the-box caching for all read operations. Every data request sent to the server is being remembered by the document store object, so subsequent  read operation that are detected as identical can return immediately.

However, it is important to beware of common pitfalls which may cause you not to take advantage of this handy feature. While there's no real way to mess up with simple Load operations, it is very easy to do that when querying.

For example, the most common query in an application like EventsZilla is to get events starting before or after a certain point in time, usually DateTimeOffset.Now. However, a query like this is guaranteed to never use the cache, since it is virtually different every time it is called.

In EventsZilla we can fix this relatively easily, by lowering the DateTimeOffset resolution when querying. Another approach will be to round up (or down) the value. The actual resolution or rounding approach we use will determine how much of caching this query will take advantage of.

Relevant code can be found here.

Aggressive caching

Basic caching is very effective, requires no action from the user's end to work, and is a great feature for automatically improving your applications performance. However, a server query is still issued with every read operation to make sure the cache never goes stale. The actual benefit with basic caching is with getting back a quick response of a thin 304 (HTTP for "I haven't changed") instead of a complete 200 response with all the requested data.

At times, we load an object - or perform a query - that we really don't care if it changes for a certain period of time, or we just don't expect it to. If we choose to, we can tell RavenDB not to query the database at all if it has a cached response that is not older than a given point in time.

This feature is called an Aggressive Caching, being aggressive in the sense of not peeking outside the cache at all. Unlike basic caching it is an opt-in feature.

In EventsZilla, this is exactly the case with a website-wide config object. We don't expect it to change a lot, and when it changes, we can bear a certain amount of time until the changes are noticeable in our website.

All we need to do to make it happen is load that object within a context of an AggressiveCache, and the RavenDB Client API will take care of the rest for us.

Using Aggressive Caching is as simple as this:

using (RavenSession.Advanced.DocumentStore.AggressivelyCacheFor(TimeSpan.FromMinutes(30)))
{
    var siteConfig = RavenSession.Load<SiteConfig>(SiteConfig.ConfigName);
}

More on caching

Is in the second part of the excellent RavenOverflow video, available here.


Showing 2 posts out of 2 total, page 1