The content you're reading is getting on in years
This post is on the older side and its content may be out of date.
Be sure to visit our blogs homepage for our latest news, updates and information.
This is going to be a HOW to configure the search indexes in sitefinity to index and search on more than the default fields.
1. You have to add the fields in sitefinity search index. The search system is based on the publishing system so the way to add additional fields is like this :
var ContentSearchPipesSettigns = PublishingSystemFactory.GetTemplatePipes("SearchItemTemplate").Where(ps => ps.PipeName == ContentInboundPipe.PipeName && ps.IsInbound).FirstOrDefault();
if (!ContentSearchPipesSettigns.Mappings.Mappings.Any(mp => mp.DestinationPropertyName == "TestField"))
{
var mapping = PublishingSystemFactory.CreateMapping("TestField", TransparentTranslator.TranslatorName, false, "TestField");
ContentSearchPipesSettigns.Mappings.Mappings.Add(mapping);
PublishingSystemFactory.RegisterTemplatePipe("SearchItemTemplate", ContentSearchPipesSettigns, ps => ps.PipeName == ContentInboundPipe.PipeName && ps.IsInbound);
}
var searchPipesSettigns = PublishingSystemFactory.GetTemplatePipes("SearchItemTemplate").Where(ps => ps.PipeName == SearchIndexOutboundPipe.PipeName && !ps.IsInbound).FirstOrDefault();
if (!searchPipesSettigns.Mappings.Mappings.Any(mp => mp.DestinationPropertyName == "TestField"))
{
var mappingTest = PublishingSystemFactory.CreateMapping("TestField", TransparentTranslator.TranslatorName, false, "TestField");
searchPipesSettigns.Mappings.Mappings.Add(mappingTest);
PublishingSystemFactory.RegisterTemplatePipe("SearchItemTemplate", searchPipesSettigns, ps => ps.PipeName == SearchIndexOutboundPipe.PipeName && !ps.IsInbound);
}
First we add a field named "TestField" in the inbound pipe and second part add the field into the search index pipe. This is changing the default search index template so all your search indexes should be recreated (deleted and created again) to apply this settings.
2. Now you have the field in the search index. So now you have to replace the provider to be able to have control over the fields that are part of the search queries :
var section = Config.Get<
SearchConfig
>();
foreach (var provider in section.Providers.Values)
{
if (provider.Name == "LuceneSearchProvider")
{
if (provider.ProviderType == typeof(LuceneSearchProvider))
{
provider.ProviderType = typeof(LucenseCustomSearchProvider);
ConfigManager.GetManager().SaveSection(section);
break;
}
}
}
3. You have to implement this Custom lucene search provider like this :
public class LucenseCustomSearchProvider : LuceneSearchProvider
{
public override IResultSet Find(string catalogueName, string query, int skip, int take, params string[] orderBy)
{
return new LuceneCustomResultSet(this, catalogueName, query, skip, take, orderBy);
}
public override IResultSet Find(string catalogueName, string query, params string[] orderBy)
{
return new LuceneCustomResultSet(this, catalogueName, query, orderBy);
}
}
4. And the last thing is to implement the custom search result set :
public class LuceneCustomResultSet : LuceneResultSet
{
public LuceneCustomResultSet(LuceneSearchProvider provider, string catalogueName, string query, params string[] orderBy)
: this(provider, catalogueName, query, 0, 0, orderBy)
{
}
string catalogueName = String.Empty;
public LuceneCustomResultSet(LuceneSearchProvider provider, string catalogueName, string query, int skip, int take, params string[] orderBy)
: base(provider, catalogueName, query, 0, 0, orderBy)
{
this.catalogueName = catalogueName;
this.query = query;
}
protected override void ExecuteQuery(bool tryToFix = true)
{
try
{
var path = ((LuceneSearchProvider)SearchManager.GetManager("").Provider).GetCataloguePath(catalogueName);
if (System.IO.Directory.Exists(path))
{
var defautlOperator = QueryParser.AND_OPERATOR;
var analyzer = this.GetAnalyzer();
var parser = new MultiFieldQueryParser(new string[] { "Title", "Content", "TestField" }, analyzer);
parser.SetDefaultOperator(defautlOperator);
//query = QueryParser.Escape(query);
if (searcher != null)
searcher.Close();
searcher = new IndexSearcher(path);
Query queryObj = searcher.Rewrite(parser.Parse(query));
Query = queryObj;
//Search only for current language
if (AppSettings.CurrentSettings.Multilingual == true)
{
TermQuery languageQuery = new TermQuery(new Term("Language", CultureInfo.CurrentUICulture.Name));
TermQuery languageNullQuery = new TermQuery(new Term("Language", SearchProvider.FieldNullValue));
BooleanQuery filterQuery = new BooleanQuery();
filterQuery.Add(languageQuery, BooleanClause.Occur.SHOULD);
filterQuery.Add(languageNullQuery, BooleanClause.Occur.SHOULD);
QueryFilter languageFilter = new QueryFilter(filterQuery);
this.hits = searcher.Search(queryObj, languageFilter);
}
else
{
this.hits = searcher.Search(queryObj);
}
for (var iter = 0; iter < this.HitCount; iter++)
{
var doc = this.hits.Doc(iter);
}
}
}
catch (Exception ex)
{
if (tryToFix && ex is ParseException)
{
this.query = this.TryFixQuery(this.query);
this.ExecuteQuery(false);
}
else
{
this.error = ex;
this.hits = null;
}
}
}
private Exception error;
private string query;
private IndexSearcher searcher;
public void Dispose()
{
if (this.searcher != null)
{
this.searcher.Close();
this.searcher = null;
}
}
}
Note that steps 3 and 4 will be changed at some point to be able to achieve this in less steps and less code.
View all posts from The Progress Team on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites
Progress collects the Personal Information set out in our Privacy Policy and the Supplemental Privacy notice for residents of California and other US States and uses it for the purposes stated in that policy.
You can also ask us not to share your Personal Information to third parties here: Do Not Sell or Share My Info
We see that you have already chosen to receive marketing materials from us. If you wish to change this at any time you may do so by clicking here.
Thank you for your continued interest in Progress. Based on either your previous activity on our websites or our ongoing relationship, we will keep you updated on our products, solutions, services, company news and events. If you decide that you want to be removed from our mailing lists at any time, you can change your contact preferences by clicking here.