Copied to clipboard

Flag this post as spam?

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


  • Euan Rae 105 posts 135 karma points
    Mar 16, 2012 @ 17:42
    Euan Rae
    0

    Auto-generated Ids for custom examine index table

    I have several custom examine indexes that are generated from SQL db tables.  I have an issue where one of the tables is just a relationship table where it has 2 foreign keys from other tables.  It's fine to generate the index from scratch, as I can just set a counter for the id.

    The issue is when I want to add lots of records directly into the index; I have been trying to get the last id in the index and adding 1 to it, but due to it's nature, if I'm adding lots of records at once, the index isn't always up to date.

    So my question is; is there anyway to configure an index to automatically generate an id?

    Anyhelp would be greatly appreciated.

    Cheers

  • Anthony Dang 1404 posts 2558 karma points MVP 3x c-trib
    Mar 18, 2012 @ 22:01
    Anthony Dang
    0

    Are you talking about generating a db id?

    Can you paste the code for your inserting here?

     

  • Euan Rae 105 posts 135 karma points
    Mar 19, 2012 @ 10:30
    Euan Rae
    0

     

    Yep, essentially, as examine needs a unique integer in the "__NodeId" field.

    This is what's in the ISimpleDataService to rebuild the entire index

     

     

    public IEnumerable<SimpleDataSet> GetAllData(string indexType)
    {
    ...
    ...
    var allItemsTags = provider.GetContentItemHasTag();
    int count = 1;
    foreach(var itemTag in allItemsTags)
    {
    var sds = new SimpleDataSet
    {
    NodeDefinition = new IndexedNode(),
    RowData = new Dictionary<string, string>()
    };
    sds.NodeDefinition.NodeId = count;
    sds.NodeDefinition.Type = "CustomData";
    sds.RowData.Add("contentItemId", itemTag.contentItemId.ToString());
    sds.RowData.Add("tagId", itemTag.tagId.ToString());
    yield return sds;
    count++;
    }
    }

    So, rebuilding the entire index is fine, as I can just create a counter.

    The issue is when I'm inserting multiple records at once.

     

    // Get all existing items in the index
    var searchResults =
    SearchProvider.Search(
    SearchProvider.CreateSearchCriteria(IndexTypes.Content).SearchIndexType,
    true
    );
    // Get the largest id and add 1 * this is what's causing the issue
    int id = searchResults.Max(sr => sr.Id) + 1;
    var dataSet = new Dictionary<string, string>
                                         {
                                             {"Id", id.ToString()},
                                             {"contentItemId", item.contentItemId.ToString()},
                                             {"tagId", item.tagId.ToString()}
                                         };
     
    IndexProvider.ReIndexNode(
    dataSet.ToExamineXml(id, "CustomData"),
    "CustomData
    );

    As the index isn't immediately update, the line

    int id = searchResults.Max(sr => sr.Id) + 1;

    will return the same id if trying to insert more than 1 record at once.

     

    Any ideas?

     

  • Anthony Dang 1404 posts 2558 karma points MVP 3x c-trib
    Mar 19, 2012 @ 11:39
    Anthony Dang
    0

    Could this be due to examine doing indexing asynchronosly?

    I think there's an option to turn that off in the new examine.

    Otherwise, could you do this at the start

    myGlobalCounter= searchResults.Max(sr => sr.Id)+1;

    Ie. store this value globally?

    Is that an option or are you threading?

     

  • Euan Rae 105 posts 135 karma points
    Mar 20, 2012 @ 10:33
    Euan Rae
    0

    I think it's due to the fact that when you add/update an item in an index, it doesn't directly insert it, it just puts a file in the queue and if the files in the queue build up faster than there added to the index, you're not going to be counting the latest items in the index.

     I thought about holding a global counter, but the site, including the CMS, is running on 2 servers.  I ended up having the content item id as the id for the record in the index and using comma-seperated ids for the tags.

    Not really ideal, but after a few tests the performance is barely affected.

  • Anthony Dang 1404 posts 2558 karma points MVP 3x c-trib
    Mar 21, 2012 @ 11:00
    Anthony Dang
    0

    I'm not sure if it fits your situation, but I wouldn't recommend using content/document nodes to store real time indexes or counters.

    You may have a situation where both servers insert at the same time and that content node is not updated.

    Scenario:

    s1: Get document node
    s2: Get document node
    s2: Change id
    s1: now has an incorrect id

    I had a scenario recently were I needed to store up-to-date counters  but had this concurrency problem with 2 servers... I ended up using the entity framework because it has the OptimisticConcurrencyException which allows you to know if your database has been changed since you created your object: http://msdn.microsoft.com/en-us/library/system.data.optimisticconcurrencyexception.aspx

    It's an edge case but could happen. Might be worth a look.

     

     

Please Sign in or register to post replies

Write your reply to:

Draft