Меня интересует вопрос о использовании связки 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.
Здравствуйте, pr0ff, Вы писали:
P>Здравствуйте, mnemtsan, Вы писали: M>>1. MS Sql Full-Text Search (компонент MS SQL 2005/2008).
P>У меня используется первый вариант (правда пока с LINQ). Вполне устраивает.
Спасибо за ответ.
Верно ли я понял что под LINQ вы имели в виду LINQ в BLT?
Скажите, есть ли проблемы со связкой ORM + SQL Full-Text Search?
Т.е такие, что содержат как полнотекстовые критерии так и строгие.
Морфология, ранжирование работают нормально(более подходящие результаты находятся на более высоких местах).
Здравствуйте, mnemtsan, Вы писали:
M>Верно ли я понял что под LINQ вы имели в виду LINQ в BLT?
Нет. Имелся в виду M$ LINQ to SQL M>Скажите, есть ли проблемы со связкой ORM + SQL Full-Text Search?
Нет, для ORM это просто как UDF.
M>Нормально ли работают запросы в духе: 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);
Здравствуйте, pr0ff, Вы писали:
P>Здравствуйте, mnemtsan, Вы писали:
M>>Верно ли я понял что под LINQ вы имели в виду LINQ в BLT? P>Нет. Имелся в виду M$ LINQ to SQL M>>Скажите, есть ли проблемы со связкой ORM + SQL Full-Text Search? P>Нет, для ORM это просто как UDF.
M>>Нормально ли работают запросы в духе: 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?
Здравствуйте, mnemtsan, Вы писали:
M>Понятно, думаю BLT должен работать через UDF.
В BLT, наверно, можно и без UDF обойтись: http://www.rsdn.ru/projects/rfd/linq/LinqWithBLToolkit.xml#EMHAG
M>Скажите, а вы не смотрели в сторону Lucene.Net и проекта LinqToLucene?
Смотрел Lucene.Net, но посчитал, что незачем усложнять архитектуру.