Q1: я делаю поиск, используя Lucene. Все работает отлично и быстро. Когда я попытался найти фразу «.net», ничего не нашел. Может быть, вы знаете, как я могу справиться с этим.
Q2: Как я могу искать и игнорировать регистр?
Обновление 1
Q1: я сохраняю задания, используя SimpleLucene . Вот код:
DirectoryIndexWriter _indexWriter = new DirectoryIndexWriter(new DirectoryInfo(indexPath), true);
using (var indexService = new IndexService(_indexWriter))
{
var result = indexService.IndexEntities(jobsTempArray, new JobIndexDefinition());
Console.WriteLine("{0} products indexed in {1} milliseconds.", result.Count, result.ExecutionTime);
}
Файл JobIndexDefinition:
public class JobIndexDefinition : IIndexDefinition<LucenceJobModel>
{
public Document Convert(LucenceJobModel job)
{
var document = new Document();
document.Add(new Field("jobtitle", job.JobTitle, Field.Store.YES, Field.Index.ANALYZED));
document.Add(new Field("AreaCode", job.AreaCode.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("Company", job.Company, Field.Store.YES, Field.Index.NOT_ANALYZED));
var dateValue = DateTools.DateToString(job.DatePosted.Value, DateTools.Resolution.MILLISECOND);
document.Add(new Field("DatePosted", dateValue, Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("Description", job.Description, Field.Store.YES, Field.Index.ANALYZED));
document.Add(new Field("Expierence", job.Expierence, Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("JobType", job.JobType, Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("Link", job.Link, Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("LinkId", job.LinkId.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("Location", job.Location, Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("PayRate", job.PayRate, Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("Source", job.Source, Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("TaxTerm", job.TaxTerm, Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("Term", job.Term, Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("Title", job.Title, Field.Store.YES, Field.Index.NOT_ANALYZED));
return document;
}
public Term GetIndex(LucenceJobModel job)
{
return new Term("Link", job.Link);
}
}
Я ищу поля JobTitle, Description и DatePosted. Вот код поиска:
public List<LucenceJobModel> JobsSearch(string keyword, string location, PageInfo pageInfo)
{
string[] words = keyword.Split(new[] { ' ' });
IndexReader reader = IndexReader.Open(SmartSearch.Instance.GetDirectory(), true);
var searcher = new IndexSearcher(reader);
var standardAnalyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29);
var fields = new[] { "JobTitle", "Description", "DatePosted" };
var searchQuery = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29, fields, standardAnalyzer);
//searchQuery.SetAllowLeadingWildcard(true);
// perform the search
var query = new BooleanQuery();
foreach (var word in words)
{
if (!String.IsNullOrEmpty(word))
{
var qTemp = searchQuery.Parse(word);
var q = searchQuery.Parse(qTemp.ToString().Substring(qTemp.ToString().LastIndexOf(":") + 1) + "*");
query.Add(q, BooleanClause.Occur.MUST);
}
}
int maxDocs = 1;
if (reader.MaxDoc() > 0)
maxDocs = reader.MaxDoc();
var results = searcher.Search(query, filter, maxDocs);
foreach (var scoreDoc in results.scoreDocs)
{
var document = searcher.Doc(scoreDoc.doc);
}
var jobs = new List<LucenceJobModel>();
for (int i = 0; i < results.scoreDocs.Length; i++)
{
var document = searcher.Doc(results.scoreDocs[i].doc);
if (i >= (pageInfo.CurrentPage - 1) * pageInfo.ItemsPerPage && i < pageInfo.CurrentPage * pageInfo.ItemsPerPage)
{
jobs.Add(LucenceJobModel.ConvertFromDoc(document));
}
itemsForGroup.Add(new ItemGroupFor
{
Company = document.GetField("Company").StringValue(),
DatePosted = DateTools.StringToDate(document.GetField("DatePosted").StringValue()),
JobType = document.GetField("JobType").StringValue(),
Location = document.GetField("Location").StringValue(),
Source = document.GetField("Source").StringValue(),
Title = document.GetField("Title").StringValue()
});
}
pageInfo.TotalItems = results.scoreDocs.Length;
return jobs;
}
Я хочу иметь возможность искать ключевые слова, такие как "C #" или ".net", не удаляя "#" или ".".
Q2: я ищу в поле Местоположение. Вот код:
public List<string> GetLocations(string term)
{
IndexReader reader = IndexReader.Open(SmartSearch.Instance.GetDirectory(), true);
var searcher = new IndexSearcher(reader);
var standardAnalyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29);
QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "Location", standardAnalyzer);
string str = parser.Parse(term).ToString().Substring(parser.Parse(term).ToString().LastIndexOf(":") + 1);
PrefixQuery q = new PrefixQuery(new Term("Location", string.Format("{0}", str)));
TopDocs results = searcher.Search(q, 5000);
return results
.scoreDocs
.Select(x => searcher.Doc(x.doc))
.Select(x => x.GetField("Location").StringValue())
.Distinct()
.ToList();
}
Я хочу найти «Нью-Йорк», «Нью-Йорк» и так далее. Но я знаю, что он ищет, только если дело верно.