Search in Sharepoint
Опубликовано: 8 ноября, 2008 Filed under: search, sharepoint | Tags: CONTAINS, FREETEXT, FullTextSqlQuery, KeywordQuery, moss, scope, search, sharepoint, wss Оставьте комментарийВот я и добрался до поиска в Sharepoint, скажу сразу, что поначалу всё очень запутанно и непросто.
Для начала немного выдержек из SDK:
Синтаксис запросов.
Классификация условно делится на работу с объектной моделью (ОМ) и веб-сервисом поиска.
Поиск в Windows SharePoint Services через ОМ поддерживает три типа синтаксиса для поддержки различных построителей запросов:
- Windows SharePoint Services Search Keyword Syntax (условия поиска передаются непосредственно в службу поиска)
- Windows SharePoint Services Search SQL Syntax (расширенный синтаксис SQL-диалекта запросов к базам данных)
- Windows SharePoint Services Search URL Syntax (все параметры отсылаются в URL и обрабатываеются непосредственно на странице поиска)
Поиск через веб-сервис, его преимущество в том, что производить поисковые операции можно с клиентских приложений, расположенных удаленно, относительно серверов с Sharepoint.
Доступ к сервису и его методам производится по адресу:
http://Server_Name/%5BSite_Name/%5D_vti_bin/spsearch.asmx
С веб-сервисами мне ещё не пришлось разбираться, поэтому описание пока будет опущенно.
А вот с объектной моделью поработать удалось.
Итак, конфигурация моей рабочей станции:
- Microsoft SQL Server 2008 Express Edition with Advanced Tools
- Microsoft Windows Sharepoint Services 3.0 SP1 (v. 12.0.0.6318)
- Microsoft Search Server 2008 Express Edition
Итак, объектная модель, для начала посмотрим на пространство имён Microsoft.SharePoint.Search.Query
- Query — базовый класс, использовать его у нас не получится.
- KeywordQuery — класс для получения результатов поиска, аналогичных по функционалу поисковому окошечку справа вверху в WSS. Что я имею ввиду:
DataTable resultsDataTable = new DataTable();
using (SPSite site = new SPSite("http://server"))
{
KeywordQuery query = new KeywordQuery(site);
query.QueryText = queryText;
query.ResultTypes = ResultType.RelevantResults;
ResultTableCollection resultTables = query.Execute();if (resultTables.Count > 0)
{
ResultTable relevantResults = resultTables[ResultType.RelevantResults];
resultsDataTable.Load(relevantResults, LoadOption.OverwriteChanges);
}}
return resultsDataTable;* This source code was highlighted with Source Code Highlighter.queryText — тот текст, который Вы забили бы в окошко поиска
resultsDataTable — поля в DataTable будут примерно такими: Title, Path, Author и т.д. ни на что большее расчитывать не прийдется
Может пригодится для кастомизации страницы поиска WSS. - FullTextSqlQuery — немного более расширенный функционал, предоставляет нам более расширенные возможности, во-первых потому-что поддерживает T-SQL-подобный синтаксис, а во вторых потому что предоставляет доступ к full-text’овому поиску (по словоформам и проч.), используя следующие операторы: FREETEXT(), CONTAINS().
DataTable resultsDataTable = new DataTable();
using (SPSite site = new SPSite("http://server"))
{
string queryText = "SELECT title, path, author, contenttype from Scope()";
FullTextSqlQuery query = new FullTextSqlQuery(site);
query.QueryText = queryText;
query.ResultTypes = ResultType.RelevantResults;
ResultTableCollection resultTables = query.Execute();
if (resultTables.Count > 0)
{
ResultTable relevantResults = resultTables[ResulType.RelevantResults];
resultsDataTable.Load(relevantResults, LoadOption.OverwriteChanges);
}
}return resultsDataTable;* This source code was highlighted with Source Code Highlighter.Scop’ы можно редактировать (по адресу http://SERVER_ADMIN/_layouts/viewscopesssp.aspx?mode=ssp). Всё великолепно, можно производить деление на страницы (копать сюда: query.StartRow, query.RowLimit, relevantResults.TotalRows(независимо от ограничений RowLImit)), сортировку, фильтрацию и проч., НО когда необходимо будет вывести результаты по полям Вашего контент-тайпа Вы упрётесь в стену, и вот тогда мы переходим к пространству имён Microsoft.Office.Server.Search.Query и аналогичной иерархии классов.
Microsoft.Office.Server.Search.Query
Для того, чтобы искать по полям Вашего контент-тайпа, необходимо зарегестрировать т.н. бегунки (crawlers), в помощь Вам вот такой метод:
private static void SetMapping(SearchContext context, string crawledPropertyName, string managedPropertyName, ManagedDataType managedDataType)
{
Schema sspSchema = new Schema(context);
//получаем управляемые свойства
ManagedPropertyCollection mproperties = sspSchema.AllManagedProperties;CategoryCollection cc = sspSchema.AllCategories;
//ищем бегунок
CrawledProperty cProp = null;
foreach (Category category in cc)
{
foreach (CrawledProperty property in category.GetAllCrawledProperties())
{
if (property.Name == crawledPropertyName)
{
cProp = property;
break;
}}
}if (cProp == null)
throw new Exception("Свойство для поиска " + crawledPropertyName + " не найдено");ManagedProperty mProp = null;
if (mproperties.Contains(managedPropertyName))
{
mProp = mproperties[managedPropertyName];
}
else
{
mProp = mproperties.Create(managedPropertyName, managedDataType);
}Mapping newMapping = new Mapping(cProp.Propset, cProp.Name, cProp.VariantType, mProp.PID);
MappingCollection mappings = mProp.GetMappings();
if (mappings.Contains(newMapping))
{
//если сопоставление уже есть уходим
return;
}
mappings.Add(newMapping);
mProp.SetMappings(mappings);
mProp.EnabledForScoping = true;
mProp.Update();
}* This source code was highlighted with Source Code Highlighter.
Пользоваться им таким образом:
SearchContext context;
using (SPSite site = web.Site)
{
context = SearchContext.GetContext(site);
}
SetMapping(context, "ows_FileLeafRef", "FileLeafRef", ManagedDataType.Text);
SetMapping(context, "ows_ChangesDateTime", "ChangesDateTime", ManagedDataType.DateTime);
* This source code was highlighted with Source Code Highlighter.
Кстати, я так и не смог найти типы в бегунках, поэтому пришлось написать свой нумератор для этих целей:
enum CrawledPropertyVariantType
{
Integer = 20,
Text = 31
}* This source code was highlighted with Source Code Highlighter.
И после регистрации необходимых Вам полей, надо переиндексировать области поиска:
//Обновим области поиска
Scopes scopes = new Scopes(context);
scopes.StartCompilation();Content sspContent = new Content(context);
ContentSourceCollection sspContentSources = sspContent.ContentSources;
foreach (ContentSource cs in sspContentSources)
{
cs.StartFullCrawl();
}
//через время всё обновится* This source code was highlighted with Source Code Highlighter.
Ссылки по теме:
- http://www.codeplex.com/sct — Search Community Toolkit. Подборка ресурсов на кодеплексе посвященных поиску в sharepoint.