Полнотекстовый поиск в BLT
От: mnemtsan  
Дата: 05.10.10 12:36
Оценка:
Здравствуйте.

Меня интересует вопрос о использовании связки BLT + полнотекстовый поиск.
Допустим мы делаем DAL на BLT и у нас возникает задача полнотекстового поиска по нашим данным.

На текущий момент я знаю 2 подходящих средства для решения этой проблемы:
1. MS Sql Full-Text Search (компонент MS SQL 2005/2008).
2. Lucene.Net (порт с Java известного полнотекстового движка Lucene).

В первом случае BLT можно интегрировать при помощи вызовов функций БД CONTAINS и FREETEXT.
Во втором можно построить индекс Lucene так, чтобы он содержал все необходимые нам поля по которым мы можем искать + Id записи.
Тогда поиск будет выглядеть следующим образом — исходно мы ищем с использованием Lucene, далее мы просим BLT вернуть объекты с нужными нам Id-ми.

Возможно кто-то уже решал такую задачу. Что можете сказать относительно вышеописанных вариантов? Есть ли более правильные и простые решения?
Кстати, возможно есть аналоги проекта Hibernate Search(http://www.hibernate.org/subprojects/search.html) — он как-раз таки интегрирует Hibernate(работа с доменной моделью) и поиск через Lucene.
Re: Полнотекстовый поиск в BLT
От: pr0ff  
Дата: 10.11.10 12:58
Оценка:
Здравствуйте, mnemtsan, Вы писали:
M>1. MS Sql Full-Text Search (компонент MS SQL 2005/2008).

У меня используется первый вариант (правда пока с LINQ). Вполне устраивает.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Re[2]: Полнотекстовый поиск в BLT
От: mnemtsan  
Дата: 11.11.10 15:57
Оценка:
Здравствуйте, pr0ff, Вы писали:

P>Здравствуйте, mnemtsan, Вы писали:

M>>1. MS Sql Full-Text Search (компонент MS SQL 2005/2008).

P>У меня используется первый вариант (правда пока с LINQ). Вполне устраивает.


Спасибо за ответ.

Верно ли я понял что под LINQ вы имели в виду LINQ в BLT?
Скажите, есть ли проблемы со связкой ORM + SQL Full-Text Search?

Нормально ли работают запросы в духе:
Where(p=>(p.Name.Contains(text) || p.Description.Contains(text)) && p.Category == selectedCategory)

Т.е такие, что содержат как полнотекстовые критерии так и строгие.
Морфология, ранжирование работают нормально(более подходящие результаты находятся на более высоких местах).

Спасибо.
Re[3]: Полнотекстовый поиск в BLT
От: pr0ff  
Дата: 11.11.10 17:05
Оценка:
Здравствуйте, mnemtsan, Вы писали:

M>Верно ли я понял что под LINQ вы имели в виду LINQ в BLT?

Нет. Имелся в виду M$ LINQ to SQL
M>Скажите, есть ли проблемы со связкой ORM + SQL Full-Text Search?
Нет, для ORM это просто как UDF.

M>Нормально ли работают запросы в духе:

M>
M>Where(p=>(p.Name.Contains(text) || p.Description.Contains(text)) && p.Category == selectedCategory)
M>

Проблемы те же, что и в обычном SQL (freetext ищет по всем записям, независимо от фильтров, и лимит будет ДО дополнительной фильтрации по другим условиям). К тому же этот Contains делает поиск по LIKE '%text%'.

db context:
        [Function(Name="Shop.ProductsFreeText", IsComposable=true)]
        [ProffFunction(Content="CREATE FUNCTION Shop.ProductsFreeText (@text nvarchar(4000), @limit int) RETURNS TABLE AS RETURN (SELECT [Key], Rank FROM FREETEXTTABLE(Shop.Products, *, @text, @limit))")] //для строгой типизации, у BLT, наверно, можно обойтись без этого.
        public IQueryable<FreeTextTableResult> FreeTextShopProducts(string text, int limit)
        {
            return CreateMethodCallQuery<FreeTextTableResult>(this, (MethodInfo)MethodInfo.GetCurrentMethod(), text, limit);
        }


Поиск по полнотестовому поиску и по полному соответствию. С соответствующим ранжированием:
            IQueryable<FreeTextTableResult> q =
                BaseShop.Current.Filter(db.AllShopProducts).Where(a => a.Name.Contains(text)).Take(200).Select(
                    a => new FreeTextTableResult {Key = a.ID, Rank = a.Name == text ? 3000 : 2000});
            IQueryable<FreeTextTableResult> q1 = q;
            q = q.Union(db.FreeTextShopProducts(text, 2000).Where(a => !q1.Any(b => b.Key == a.Key)));
            IQueryable<ShopProduct> query =
                BaseShop.Current.Filter(from a in q
                    join b in db.AllShopProducts on a.Key equals b.ID
                    orderby a.Rank descending , b.Inserted descending
                    select b);
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Re[4]: Полнотекстовый поиск в BLT
От: mnemtsan  
Дата: 12.11.10 10:12
Оценка:
Здравствуйте, pr0ff, Вы писали:

P>Здравствуйте, mnemtsan, Вы писали:


M>>Верно ли я понял что под LINQ вы имели в виду LINQ в BLT?

P>Нет. Имелся в виду M$ LINQ to SQL
M>>Скажите, есть ли проблемы со связкой ORM + SQL Full-Text Search?
P>Нет, для ORM это просто как UDF.

M>>Нормально ли работают запросы в духе:

M>>
M>>Where(p=>(p.Name.Contains(text) || p.Description.Contains(text)) && p.Category == selectedCategory)
M>>

P>Проблемы те же, что и в обычном SQL (freetext ищет по всем записям, независимо от фильтров, и лимит будет ДО дополнительной фильтрации по другим условиям). К тому же этот Contains делает поиск по LIKE '%text%'.

P>db context:

P>
P>        [Function(Name="Shop.ProductsFreeText", IsComposable=true)]
P>        [ProffFunction(Content="CREATE FUNCTION Shop.ProductsFreeText (@text nvarchar(4000), @limit int) RETURNS TABLE AS RETURN (SELECT [Key], Rank FROM FREETEXTTABLE(Shop.Products, *, @text, @limit))")] //для строгой типизации, у BLT, наверно, можно обойтись без этого.
P>        public IQueryable<FreeTextTableResult> FreeTextShopProducts(string text, int limit)
P>        {
P>            return CreateMethodCallQuery<FreeTextTableResult>(this, (MethodInfo)MethodInfo.GetCurrentMethod(), text, limit);
P>        }
P>


P>Поиск по полнотестовому поиску и по полному соответствию. С соответствующим ранжированием:

P>
P>            IQueryable<FreeTextTableResult> q =
P>                BaseShop.Current.Filter(db.AllShopProducts).Where(a => a.Name.Contains(text)).Take(200).Select(
P>                    a => new FreeTextTableResult {Key = a.ID, Rank = a.Name == text ? 3000 : 2000});
P>            IQueryable<FreeTextTableResult> q1 = q;
P>            q = q.Union(db.FreeTextShopProducts(text, 2000).Where(a => !q1.Any(b => b.Key == a.Key)));
P>            IQueryable<ShopProduct> query =
P>                BaseShop.Current.Filter(from a in q
P>                    join b in db.AllShopProducts on a.Key equals b.ID
P>                    orderby a.Rank descending , b.Inserted descending
P>                    select b);
P>


Понятно, думаю BLT должен работать через UDF.

Скажите, а вы не смотрели в сторону Lucene.Net и проекта LinqToLucene?
Re[5]: Полнотекстовый поиск в BLT
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.11.10 12:45
Оценка:
Здравствуйте, mnemtsan, Вы писали:

M>Скажите, а вы не смотрели в сторону Lucene.Net


Мы смотрели.

M> и проекта LinqToLucene?


А смысл в таком проекте? И какое это имеет отношение к BLT?
... << RSDN@Home 1.2.0 alpha 4 rev. 1476 on Windows 7 6.1.7600.0>>
AVK Blog
Re[5]: Полнотекстовый поиск в BLT
От: pr0ff  
Дата: 12.11.10 15:32
Оценка:
Здравствуйте, mnemtsan, Вы писали:

M>Понятно, думаю BLT должен работать через UDF.

В BLT, наверно, можно и без UDF обойтись: http://www.rsdn.ru/projects/rfd/linq/LinqWithBLToolkit.xml#EMHAG

M>Скажите, а вы не смотрели в сторону Lucene.Net и проекта LinqToLucene?

Смотрел Lucene.Net, но посчитал, что незачем усложнять архитектуру.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.