Ответ 1
Вы можете выполнять поиск подстроки по нескольким полям, используя следующий подход:
(1)
public class IdeaByBodyOrTitle : AbstractIndexCreationTask<Idea>
{
public IdeaByBodyOrTitle()
{
Map = ideas => from idea in ideas
select new
{
idea.Title,
idea.Body
};
}
}
на этот сайт вы можете проверить, что:
"По умолчанию RavenDB использует собственный анализатор, называемый LowerCaseKeywordAnalyzer для всего содержимого. (...) Значения по умолчанию для каждое поле - FieldStorage.No в магазинах и FieldIndexing.Default в Индексы".
Итак, по умолчанию, если вы проверяете термины индекса внутри клиента raven, он выглядит следующим образом:
Title Body
------------------ -----------------
"the idea title 1" "the idea body 1"
"the idea title 2" "the idea body 2"
Исходя из этого, можно создать шаблонный запрос:
var wildquery = string.Format("*{0}*", QueryParser.Escape(query));
который затем используется с конструкциями .In
и .Where
(с использованием оператора OR внутри):
var ideas = session.Query<User, UsersByDistinctiveMarks>()
.Where(x => x.Title.In(wildquery) || x.Body.In(wildquery));
(2)
В качестве альтернативы вы можете использовать чистый запрос lucene:
var ideas = session.Advanced.LuceneQuery<Idea, IdeaByBodyOrTitle>()
.Where("(Title:" + wildquery + " OR Body:" + wildquery + ")");
(3)
Вы также можете использовать выражение .Search
, но вам нужно построить свой индекс по-разному, если вы хотите искать по нескольким полям:
public class IdeaByBodyOrTitle : AbstractIndexCreationTask<Idea, IdeaByBodyOrTitle.IdeaSearchResult>
{
public class IdeaSearchResult
{
public string Query;
public Idea Idea;
}
public IdeaByBodyOrTitle()
{
Map = ideas => from idea in ideas
select new
{
Query = new object[] { idea.Title, idea.Body },
idea
};
}
}
var result = session.Query<IdeaByBodyOrTitle.IdeaSearchResult, IdeaByBodyOrTitle>()
.Search(x => x.Query, wildquery,
escapeQueryOptions: scapeQueryOptions.AllowAllWildcards,
options: SearchOptions.And)
.As<Idea>();
Резюме:
Также имейте в виду, что *term*
довольно дорогой, особенно главный шаблон. В этом post вы можете найти дополнительную информацию об этом. Говорят, что ведущая подстановка заставит lucene выполнить полное сканирование индекса и, таким образом, может резко замедлить выполнение запросов. Lucene внутренне сохраняет свои индексы (на самом деле термины строковых полей), отсортированные по алфавиту и "читаемые" слева направо. Именно по этой причине быстро выполняется поиск конечного шаблона и медленный для ведущего.
Таким образом, можно использовать x.Title.StartsWith("something")
, но это, очевидно, не поиск по всем подстрокам. Если вам нужен быстрый поиск, вы можете изменить параметр "Индекс" для полей, которые вы хотите искать, для анализа, но он снова не будет искать по всем подстрокам.
Если в запросе подстроки есть пробел, проверьте это question для возможного решения. Для внесения предложений проверьте http://architects.dzone.com/articles/how-do-suggestions-ravendb.