Content Sources
According to the Architecture a content source is responsible to get new content to be indexed. The steps to develop a custom content source would be:
- Add a configuration file in ContentSources folder (see local .readme.txt)
- Create your own project with a class that implements
DnnSharp.SearchBoost.Core.ContentSource.IContentSource
- implement the Query method that returns a
IEnumerable<Core.Indexing.IndexingJob>
. - implement ComputeResultUrl method. The default should be:
return new GenericUrlResolver(searchResult, searchContext).GetUrlForSearchResult();
- implement the Query method that returns a
For SearchBoost >= 4.0.0 you can use the following sample:
using DnnSharp.SearchBoost.Core.Behaviors;
using DnnSharp.SearchBoost.Core.ContentSource;
using DnnSharp.SearchBoost.Core.Indexing;
using DnnSharp.SearchBoost.Core.Search;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace MyImplementation.MyContentSources {
public class FirstContentSource : IContentSource {
public static int StartId { get; set; } = 0;
public string ComputeResultUrl(SbSearchResult searchResult, SearchContext searchContext) {
return new GenericUrlResolver() {
SearchResult = searchResult,
SearchContext = searchContext
}.GetUrlForSearchResult();
}
const string MyContent = @"My Test Content";
public IEnumerable<IndexingJob> Query(SearchBehavior behavior, DateTimeOffset? since, CancellationToken cancellationToken) {
for (var i = StartId; i < StartId + 10; i++) {
var job = new IndexingJob();
job.ContentSourceId = "DnnModules";
job.Due = DateTimeOffset.Now;
job.DatePublished = DateTimeOffset.Now;
job.Action = "add";
job.Priority = ePriorityIndexingJob.Low;
job.BehaviorId = behavior.Id;
job.PortalId = 0;
job.TabId = 1;
job.ModuleId = 1;
job.Metadata.Type = "mod";
job.Metadata.SubType = "Test Module";
job.Metadata.Url = "";
job.ItemId = "test-" + i;
job.Metadata.Title = "Test " + i;
job.Contents = Encoding.UTF8.GetBytes(MyContent);
job.ContentType = "text/plain";
job.Metadata.DatePublished = DateTimeOffset.Now;
job.Metadata.ItemId = job.ItemId;
job.Metadata.ItemPath = "test/"+i;
job.Metadata.ContainerId = "Test";
job.Metadata.ContainerName = "Test";
job.Metadata.ContainerPath = "Test";
yield return job;
}
}
}
}
Note that you can use the IndexingJob class to create your own job in other places of your code and simply call the Save() method on that job object,
[Common2.IoC.IoCService]
Common2.Services.Dnn.IPortalService PortalService { get; set; }
void SaveJob(SearchBehavior behavior) {
var job = new IndexingJob();
job.ContentSourceId = "DnnModules";
job.Due = DateTimeOffset.Now;
job.DatePublished = DateTimeOffset.Now;
job.Action = "add";
job.Priority = ePriorityIndexingJob.Low;
job.BehaviorId = BehaviorService.GetDefaultBehavior(PortalService.GetCurrentPortalSettings().PortalId).Id; // all jobs must belong to a behavior
// or you can get it by name using:
// job.BehaviorId = BehaviorService.GetAll().FirstOrDefault(x => x.Name == behaviorName && x.PortalId == portalId)
job.PortalId = 0;
job.TabId = 1;
job.ModuleId = 1;
job.Metadata.Type = "mycustomtype";
job.Metadata.SubType = "SomeSubType";
job.Metadata.Url = ""; // you can add here a custom url for search result, otherwise it will redirect to the specified tabid property
job.ItemId = "MyUniqueId";
job.Metadata.Title = "Job Title In Results";
job.Contents = Encoding.UTF8.GetBytes("My Custom Content");
job.ContentType = "text/plain";
job.Metadata.DatePublished = DateTimeOffset.Now;
job.Metadata.ItemId = job.ItemId;
job.Metadata.ItemPath = "test/path_if_needed"; // useful for files, to get them from DNN when using the DnnFileClient content client
job.ContentClient = "MyCustomContentClient"; // Content clients are defined in /Config/ContentClients folders, and here you type their ID property, like "WebClient" or "DnnFile"
job.ContentClientOptions = new Common.SettingsDictionary(); // this is pased to the content client for further options. Not needed for the default ones.
job.Metadata.ContainerId = "Test";
job.Metadata.ContainerName = "Test";
job.Metadata.ContainerPath = "Test";
job.Save();
}
Older Versions
Here is a sample that works with SearchBoost >= 3.1.43, up until SearchBoost <= 4.0.0:
using DnnSharp.SearchBoost.Core.ContentSource;
using DnnSharp.SearchBoost.Core.Indexing;
using DnnSharp.SearchBoost.Core.Search;
using DnnSharp.Common.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace avt.SearchBoost.TestPlugin.ContentSources
{
public class TestContentSource : IContentSource
{
public void Query(TypedLogger<SearchInstance> logger, Core.Indexing.LuceneStorage dataStore, Core.IEngineSettings config, Core.Indexing.IndexingStatistics stats) {
}
public IEnumerable<Core.Indexing.IndexingJob> Query(SearchInstance instance, DateTimeOffset? since, TypedLogger<SearchInstance> logger) {
List<IndexingJob> toReturn = new List<IndexingJob>();
// creating a new indexing job using the contructor with required properties:
IndexingJob job = new IndexingJob(instance, contentSourceId: "MyContentSourceId", action: "add", type: "plugin",
itemId: "uniqueJobId", title: "Title", portalId: 0);
// we want the item to be indexed right away
job.Due = DateTime.Now;
// the job will have a higher priority
job.Priority = ePriorityIndexingJob.High;
// let's say the item was last modified yesterday
job.Metadata.DatePublished = DateTime.Now.AddDays(-1).ToUniversalTime();
// show item in results for all users (using DNN user roles)
job.Metadata.Roles = new List<string> { "All Users" };
job.Metadata.OriginalName = "Item original name";
// the item result url will have added the following query string params:
job.Metadata.QueryString = "Param1=value&Param2=otherValue";
// the content that will be indexed and used for result description:
job.Contents = Encoding.UTF8.GetBytes("xyz content");
// show this description (if "Highlight search terms" is disabled)
job.Metadata.Description = "custom description";
// this is saved in index (not searchable)
// can accessed in your custom output template with <xsl:value-of select="data/field[@name='somekey']"></xsl:value-of> (returns first element = data1)
// you can also filter by appending query string param sbc-somekey=filterValue
job.Metadata.Data.Add(new Core.Model.CustomData {
Name = "somekey",
Values = new List<string> { "data1", "data2" }
});
// other properties:
job.Metadata.ContainerId = "container id";
job.Metadata.ContainerName = "container name";
toReturn.Add(job);
return toReturn;
}
public string ComputeResultUrl(Core.Search.SbSearchResult searchResult, Core.Search.SearchContext searchContext) {
return new GenericUrlResolver(searchResult, searchContext).GetUrlForSearchResult();
}
}
}