Вы можете создать такое решение с помощью Lucene .Net.
Храните ваши документы в базе данных (как уже было) и индексируйте с помощью документов Lucene.Net, которые вы хотите.
Lucene будет иметь свой собственный индекс в файловой системе.
Вам необходимо обеспечить синхронизацию между своими документами в БД и индексом Lucene, поэтому, когда документ в БД изменяется, вам необходимо переиндексировать его с помощью Lucene.
Синхронизация (сопоставление между БД и индексом Lucene) может основываться на некотором уникальном значении ключа из БД (например, ID).
Итак, когда вы хотите добавить какой-либо документ в индекс Lucene, вы индексируете содержимое документа (вам не нужно сохранять содержимое в Lucene) и «сохраняете» его в Lucene с уникальным значением ключа из DB (скажем, ID). ).
Затем вы можете выполнить поиск по индексу Lucene и получить список соответствующих идентификаторов документов.
И получить их из вашей БД по этим идентификаторам и показать пользователю.
Ниже приведен пример метода из моего проекта, он добавляет документ в индекс Lucene.
InformationAsset в аргументе метода - это документ из БД, который я хочу проиндексировать.
Этот метод создает «документ Lucene» с несколькими «полями»:
- 'field': содержимое документа из db (InformationAsset из аргумента метода)
- 'fieldId': это идентификатор информационного актива из базы данных, который соответствует базе данных и индексу Lucene
- 'fieldPubDate': дата публикации, я могу создавать расширенные запросы к движку Lucene на основе всех полей.
'fieldDataSource': это какая-то категория.
public void AddToIndex(Entities.InformationAsset infAsset, IList<Keyword> additionalKeywords)
{
Analyzer analyzer = new StandardAnalyzer();
IndexWriter indexWriter = new IndexWriter(LuceneDir, analyzer, false);
Document doc = new Document();
// string z dodatkowymi slowami po ktorych ma byc tez zindeksowana tresc
string addKeysStr = "";
if(additionalKeywords != null)
{
foreach (Keyword keyword in additionalKeywords)
{
addKeysStr += " " + keyword.Value;
}
}
addKeysStr += " " + m_RootKeyword;
string contentStr;
contentStr = infAsset.Title + " " + infAsset.Content + addKeysStr;
// indeksacja pola z trescia
Field field = new Field(LuceneFieldName.Content, contentStr, Field.Store.NO, Field.Index.TOKENIZED,
Field.TermVector.YES);
// pole z Id
Field fieldId = new Field(LuceneFieldName.Id, infAsset.Id.ToString(), Field.Store.YES, Field.Index.UN_TOKENIZED);
// pole publish date
Field fieldPubDate = new Field(LuceneFieldName.PublishDate,
DateTools.DateToString(infAsset.PublishingDate, DateTools.Resolution.MINUTE),
Field.Store.YES, Field.Index.NO_NORMS, Field.TermVector.YES);
// pole DataSource
// pole z Id
Field fieldDataSource = new Field(LuceneFieldName.DataSourceId, infAsset.DataSource.Id.ToString(), Field.Store.YES,
Field.Index.UN_TOKENIZED);
doc.Add(field);
doc.Add(fieldId);
doc.Add(fieldPubDate);
doc.Add(fieldDataSource);
doc.SetBoost((float)CalculateDocBoostForInfAsset(infAsset));
indexWriter.AddDocument(doc);
indexWriter.Optimize();
indexWriter.Close();
}