Developer forum

Forum » Development » Update build with IndexBuilder

Update build with IndexBuilder

Aki Ruuskanen
Aki Ruuskanen
Reply

Hi,

In our current solution we are working on we have a number of custom indexes. I am trying to find out what the best way is to work with update builds with custom indexes. If someone can shed some light on the issue, it would be much appriciated. 

Regards / Aki


Replies

 
Nicolai Pedersen Dynamicweb Employee
Nicolai Pedersen
Reply
This post has been marked as an answer

We do it something like below:

 

[AddInName("User Index Builder")]

public class 

    : IndexBuilderBase, IResumable

{

    private const string AddInParameterGroupName = "User Index Builder Settings";


    [AddInParameterGroup(AddInParameterGroupName), AddInParameter("HoursToUpdate"), AddInLabel("Hours to update"), AddInParameterEditor(typeof(NumberParameterEditor), "")]

    public int HoursToUpdate

    {

        get => GetInt32("HoursToUpdate");

        set => SetValue("HoursToUpdate", value);

    }


    /// <summary>

    /// Gets or sets a value indicating the index opened in insert mode

    /// </summary>

    public bool Resume { get; set; }


    /// <summary>

    /// Gets or sets a list of user ids, which will be updated in the index

    /// </summary>

    public IEnumerable<int> UserIds { get; set; } = [];


    /// <summary>

    /// Gets the supported actions

    /// </summary>

    public override IEnumerable<string> SupportedActions => new[] { "Full", "Update", "UpdateWithIds" };


    /// <summary>

 /// Gets default settings collection

 /// </summary>

    public override IDictionary<string, object> DefaultSettings => new Dictionary<string, object> { { "HoursToUpdate", 24 }, { "DoNotFailOnMismatchingCount", true } };


    /// <summary>

    /// Build the index

    /// </summary>

    /// <param name="writer">An <see cref="IIndexWriter"></see> instance</param>

    /// <param name="tracker">A <see cref="Tracker"/> instance</param>

    public override void Build(IIndexWriter writer, Tracker tracker)

    {

        ArgumentNullException.ThrowIfNull(writer, nameof(writer));

        ArgumentNullException.ThrowIfNull(tracker, nameof(tracker));


        tracker.LogInformation("{0} building using {1}... Action: '{2}', Resume: '{3}'  (Threadid: {4})", GetType().FullName ?? string.Empty, writer.GetType().FullName ?? string.Empty, Action, Resume, System.Threading.Thread.CurrentThread.ManagedThreadId);

        if (string.IsNullOrEmpty(Action))

        {

            Action = "Full";

        }


        try

        {

            tracker.LogInformation("Opening index writer.");


            if (Resume || Action.Equals("Update") || Action.Equals("UpdateWithIds"))

            {

                writer.Open(true);

                tracker.LogInformation("Opened index writer for update");

            }

            else

            {

                writer.Open(false);

                tracker.LogInformation("Opened index writer to overwrite index");

            }

....

}
Then in our process method we do this:
 
Private void ProcessUsers(IDbConnection connection, IIndexWriter writer, Tracker tracker)
        {
            tracker.LogInformation($"Starting processing users. (Threadid: {System.Threading.Thread.CurrentThread.ManagedThreadId})");

            using (IDbCommand command = connection.CreateCommand())
            {
                command.CommandText = "SELECT * FROM AccessUser with (NOLOCK) WHERE AccessUserType in (1, 3, 5)";
                if (Action.Equals("UpdateWithIds"))
                {
                    command.CommandText += $" AND AccessUserID IN ({string.Join(",", UserIds)})";
                }
                else if (Action.Equals("Update"))
                {
                    command.CommandText += $" AND AccessUserUpdatedOn > {Database.SqlDate(DateTime.Now.AddHours(HoursToUpdate * -1))}";
                }
                command.CommandText += $" ORDER BY AccessUserID";

...

}
Votes for this answer: 1
 
Aki Ruuskanen
Aki Ruuskanen
Reply

Thanks, I'll take a look at it. 

/Aki

 
Aki Ruuskanen
Aki Ruuskanen
Reply

Hi,

One question about this. 

We have a custom index builder for some data. Lets say it looks like this

Field1, Field2, Field3

We use a QueryPublisher then to put the loop into the session with something llike this

Dynamicweb.Context.Current.Session["OnRentList"] = eqmRentalLineManager.CreateOnRentViewModel(GetLoop("QueryResultItem"));

Works just fine.

Then the user have the possibility to edit one of the fields. So we update the data in the source table and start an index update.  

In the indexbuilder we get the updated line from the db and open the writer like this.

writer.Open(true);

We then build the IndexDocument and put in the new data and in admin we can see that the index is updated with one row. 

But when when the page is reloaded and the data is supposed to be updated from GetLoop("QueryResultItem") the loop the index builder has appended a row to the index so  I get one row with the old value and one row with the new value. 

How can I get the Index Update to actually update the index and not append?

Regards / Aki

 

 

 

 
Aki Ruuskanen
Aki Ruuskanen
Reply

Hi,

I saw not that the write har an "AddOrUpdateDocument" method also. :) Sounds like that is the solution. 

Regards / Aki

 

You must be logged in to post in the forum