5

I'm trying to add some items to a custom Sitecore Solr index Programmatically via the Sitecore Content Search APIs. The items I will add won't reside in Sitecore so the code below is just a test for now.

I've simplified the code a bit to share an example below, however I don't know if this approach will work or not as I'm not sure how best to pass in the IProviderUpdateContext and IProviderIndexConfiguration:

using (var context = ContentSearchManager.GetIndex(indexName).CreateSearchContext())
{
    //get the home item from Sitecore
    var item = _databaseManager.GetItem(new ID("{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}"));

    //convert to an indexable item
    var searchItem = new SitecoreIndexableItem(item);

    //add the item to the index - this doesn't work
    context.Index.Operations.Add(searchItem, null, null);
}

I know that there are other ways of doing this such as creating my own search crawler using FlatDataCrawler and the GetItemsToIndex() method. However I want to run the code from SiteCron in order to have more control over when and how it happens.

I'm using Sitecore 8.2 Update 6 and Solr 6.6.3.

One way I could do this is using the Rest Apis to add data but I’d rather use the internal Apis given this runs in the Sitecore context. I’m open to other suggestions on how to do this in other ways though.

2 Answers 2

3

I answered a similar question here, but I'll paste the answer I came up with in case anyone stumbles upon this.

You're really close. You have to queue up the context first and then add and commit.

using (var solr = ContentSearchManager.GetIndex("my_index'))
{
    var ctx = solr.CreateUpdateContext();
    solr.Operations.Add(newItem, ctx, solr.Configuration);
    ctx.Commit();
}

Since this is using SolrNet under the hood, all operations against Solr have to be committed.

1
  • This doesn't use the IndexCustodian, so be careful - from the very terse Sitecore docs: doc.sitecore.com/xp/en/developers/101/… "When you invoke these methods directly on the ISearchIndex interface, it can cause various issues ranging from missing log entries to application crash due to a StackOverflowException exception. Therefore, use these API calls from the IndexCustodian class."
    – geedubb
    Sep 13, 2022 at 14:37
3

If you created an item then it should be already in the index so you just need to update/refreshe it. You can do it like that:

var tempItem = (SitecoreIndexableItem)newItem;
ContentSearchManager.GetIndex(indexName).Refresh(tempItem);

Otherwhise, you can try using the HistoryEngine. Try one of those (try also using those three at once):

item.Database.Engines.HistoryEngine.RegisterItemSaved(item, new ItemChanges(item));
item.Database.Engines.HistoryEngine.RegisterItemCreated(item);
item.Database.Engines.HistoryEngine.RegisterItemMoved(item, oldParentId);
2
  • Thanks Dawid the .Refresh(tempItem); code works great. I had in the mean-time written a crawler and called context.Index.Rebuild(); on it which also worked ok too. I'll write up a full answer later with the code for these two options when I get a minute but I think I'll probably go with .Refresh(tempItem); as it's a lot less code to manage and my Cron is already running out of Process. Jul 10, 2018 at 12:46
  • Hmm, actually after looking at this further my SearchCrawler was still firing and this code doesn't work for me, It was just my SearchCrawler confusing me. Am I missing something here?: var tempItem = new SitecoreIndexableItem(item1); using (var context = ContentSearchManager.GetIndex(_indexName).CreateSearchContext()) { context.Index.Operations.Add(tempItem, ContentSearchManager.GetIndex(_indexName).CreateUpdateContext(), ContentSearchManager.GetIndex(_indexName).Configuration); context.Index.Refresh(tempItem); } Jul 10, 2018 at 15:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.