Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Bjarne Fyrstenborg 1285 posts 4039 karma points MVP 8x c-trib
    Sep 28, 2017 @ 17:50
    Bjarne Fyrstenborg
    0

    Get current examine indexer or indexset in ISimpleDataService

    I have a custom examine indexer using the ISimpleDataService similar to this article: https://24days.in/umbraco-cms/2016/custom-data-and-examine-searching/

    public class ReviewIndexer : ISimpleDataService
    {
          public IEnumerable<SimpleDataSet> GetAllData(string indexType)
            {
                // Ensure that an Umbraco context is available
                if (UmbracoContext.Current == null)
                {
                    var dummyContext = new HttpContextWrapper(new HttpContext(new SimpleWorkerRequest("/", string.Empty, new StringWriter())));
                    UmbracoContext.EnsureContext(
                        dummyContext,
                        ApplicationContext.Current,
                        new WebSecurity(dummyContext, ApplicationContext.Current),
                        UmbracoConfig.For.UmbracoSettings(),
                        UrlProviderResolver.Current.Providers,
                        false);
                }
    
                var dataSets = new List<SimpleDataSet>();
    
                try
                {
                    var service = new ReviewService("mysite");
                    var reviews = service.LoadAllReviewsFromDisk();
    
                    // Looping all the raw models and adding them to the dataset
                    foreach (var r in reviews)
                    {
                        var simpleDataSet = new SimpleDataSet
                        {
                            NodeDefinition = new IndexedNode(),
                            RowData = new Dictionary<string, string>()
                        };
    
                        simpleDataSet = ReviewToIndexItem(r, simpleDataSet, indexType);
    
                        dataSets.Add(simpleDataSet);
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error<ReviewIndexer>("error indexing:", ex);
                }
    
                return dataSets;
            }
    
            private SimpleDataSet ReviewToIndexItem(ReviewModel r, SimpleDataSet simpleDataSet, string indexType)
            {
                simpleDataSet.NodeDefinition.NodeId = r.Id;
                simpleDataSet.NodeDefinition.Type = indexType;
                simpleDataSet.RowData.Add("id", r.Id.ToString());
                simpleDataSet.RowData.Add("name", r.Name);
                simpleDataSet.RowData.Add("date", r.Date.ToString());
                simpleDataSet.RowData.Add("destination", r.Destination);
                simpleDataSet.RowData.Add("hotel", r.Hotel);
                simpleDataSet.RowData.Add("hotelRating", r.HotelRating.ToString());
                simpleDataSet.RowData.Add("rating", r.Rating.ToString());
                simpleDataSet.RowData.Add("showComment", r.ShowComment.ToString());
                simpleDataSet.RowData.Add("text", r.Text);
                simpleDataSet.RowData.Add("photo", r.Photo);
    
                return simpleDataSet;
            }
        }
    }
    

    However "mysite" is hardcoded and with this multi-site solutions I would like to get this based on indexer name ExamineSetting.config or maybe IndexParentId or SetName on IndexSet in ExamineIndex.config. E.g. instead of "mysite" it could be the root ids or root names of each site.

    When having data as Umbraco content nodes, you can configurate Examine with IndexParentId, so it only use data with the specified parent id.

    ExamingIndex.config:

    <IndexSet SetName="MysiteExternalReviewIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/{machinename}/MysiteExternalReviewIndexSet/" IndexParentId="1234">
          <IndexUserFields>
            <add Name="id"/>
            <add Name="city"/>
            <add Name="name"/>
            <add Name="date" />
            <add Name="destination" />
            <add Name="hotel"/>
            <add Name="hotelRating"/>
            <add Name="rating"/>
            <add Name="showComment" />   
            <add Name="text"/>
            <add Name="photo"/>
          </IndexUserFields>
    </IndexSet>
    

    ExamingSettings.config:

    <add name="MysiteExternalReviewIndexer" type="Examine.LuceneEngine.Providers.SimpleDataIndexer, Examine"
                   dataService="MyProject.Library.Indexing.ReviewIndexer, MyProject.Library"
                   indexTypes="Review"
                   indexSet="MysiteExternalReviewIndexSet"
                   runAsync="false" />
    

    Can I somehow access the current indexer or indexset inside GetAllData method?

    /Bjarne

  • Bjarne Fyrstenborg 1285 posts 4039 karma points MVP 8x c-trib
    Oct 03, 2017 @ 08:15
    Bjarne Fyrstenborg
    0

    For now I request the hostname, but it requires running the indexer from the specific site domain.

    UmbracoHelper helper = new UmbracoHelper(UmbracoContext.Current);
    var host = helper.UmbracoContext.HttpContext.Request.Url.Host;
    
    if (!string.IsNullOrEmpty(host))
    {
        host = host.Replace(".", "").Trim("local").Trim("staging").Trim("test");
    }
    
    var service = new ReviewService(host);
    
  • Marcin Zajkowski 112 posts 585 karma points MVP 7x c-trib
    Oct 03, 2017 @ 21:30
    Marcin Zajkowski
    0

    Hey Bjarne,

    I don't know if this is what you're looking for, but you can grab your indexer object and do whatever you like with it as below:

    enter image description here

    var yourIndexer = (UmbracoContentIndexer)ExamineManager.Instance.IndexProviderCollection[Common.Constants.Examine.Indexers.YourIndexerAlias]; 
    

    Hope it will help you.

  • Bjarne Fyrstenborg 1285 posts 4039 karma points MVP 8x c-trib
    Oct 03, 2017 @ 21:57
    Bjarne Fyrstenborg
    0

    Hi Marcin

    Yes, I can also access a specific indexer by name from IndexProviderCollection. In this multisite project we also have some configurated examine indexes just with UmbracoContentIndexer (without any custom indexing) for example for blog indexes. These are using parentId (e.g. root node id of site) to limit the index to the specific site.

    The index sets:

    <IndexSet SetName="Site1BlogIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/{machinename}/Site1IndexSet/" IndexParentId="1234">
        <IndexAttributeFields>
          <add Name="id" />
          <add Name="nodeName"/>
          <add Name="nodeTypeAlias" />
        </IndexAttributeFields>
        <IndexUserFields>
          <add Name="blogHeader"/>
          <add Name="blogImage"/>
          <add Name="blogDate"/>
          <add Name="shortDescription"/>
          <add Name="blogAuthor"/>
          <add Name="tags"/>
          <add Name="pageContent"/>
        </IndexUserFields>
        <IncludeNodeTypes>
          <add Name="BlogPost" />
        </IncludeNodeTypes>
      </IndexSet>
    

    and the indexers:

    <IndexSet SetName="Site2BlogIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/{machinename}/Site2IndexSet/" IndexParentId="1234">
        <IndexAttributeFields>
          <add Name="id" />
          <add Name="nodeName"/>
          <add Name="nodeTypeAlias" />
        </IndexAttributeFields>
        <IndexUserFields>
          <add Name="blogHeader"/>
          <add Name="blogImage"/>
          <add Name="blogDate"/>
          <add Name="shortDescription"/>
          <add Name="blogAuthor"/>
          <add Name="tags"/>
          <add Name="pageContent"/>
        </IndexUserFields>
        <IncludeNodeTypes>
          <add Name="BlogPost" />
        </IncludeNodeTypes>
      </IndexSet>
    
    <add name="Site1BlogIndexer" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine" 
              indexSet="Site1BlogIndexSet"
              supportUnpublished="false"
              supportProtected="false"
              analyzer="Lucene.Net.Analysis.Standard.StandardAnalyzer, Lucene.Net"
              enableDefaultEventHandler="true"/>
    
    <add name="Site2BlogIndexer" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine" 
              indexSet="Site2BlogIndexSet"
              supportUnpublished="false"
              supportProtected="false"
              analyzer="Lucene.Net.Analysis.Standard.StandardAnalyzer, Lucene.Net"
              enableDefaultEventHandler="true"/>
    

    However in this case when reusing the class which inherit from ISimpleDataService for reviews indexes, I don't know if there are any way to know which of the indexers or index sets that currently are running?

    <add name="Site1ReviewIndexer" type="Examine.LuceneEngine.Providers.SimpleDataIndexer, Examine"
               dataService="MyProject.Library.Indexing.ReviewIndexer, MyProject.Library"
               indexTypes="Review"
               indexSet="Site1ReviewIndexSet"
               runAsync="true" />
    
    <add name="Site2ReviewIndexer" type="Examine.LuceneEngine.Providers.SimpleDataIndexer, Examine"
               dataService="MyProject.Library.Indexing.ReviewIndexer, MyProject.Library"
               indexTypes="Review"
               indexSet="Site2ReviewIndexSet"
               runAsync="true" />
    

    In the posted code I would like to pass in root/site node id or name in this line, since it fetch data from different external requests.

    var service = new ReviewService("mysite");
    

    /Bjarne

  • Georgios Rovolis 9 posts 80 karma points
    Oct 16, 2018 @ 16:44
    Georgios Rovolis
    0

    I don't wanna make a new thread just for this, so I'm gonna ask here!

    I have some nodes with repeatable textstrings. I am using a SimpleDataSet to create a new index and add those textstrings as separate nodes in that index. I used do tag.getHashCode() to generate a sort of unique Id for them, however I now have about 40k tags and there are way too many collision. Also, sometimes, the int returned from the getHashCode() is negative and I have to fetch the absolute value that creates even more collisions.

    So my question is, could I change the nodeId to a long integer or even a string? There are far more reliable ways to produce a unique Id if I could use a string.

    Thanks in advance.

Please Sign in or register to post replies

Write your reply to:

Draft