Knowledgebase Home Page  >  SearchUnit
Search the Knowledge Base
Uploading and indexing documents immediately. (C#)
https://keyoti.com/kb/Default.aspx?ToDo=view&questId=241&catId=54

Options

Print this page
Email this to a friend

It’s possible to index a document programmatically in codebehind using the standard DocumentIndex.AddDocument method.  However, do this you may run into problems because the indexing code won't necessarily finish before the ASP.NET page timeout. So the best way to do it (for the user as well), is to add the document asynchronously.

This is fairly straightforward (although the code looks a bit complicated).

1. Add this class to your project - it does 2 things
i) queues up new documents to be indexed, just in case 2 or more documents arrive close together.
ii) adds the document with asynchronous invoke code

 

    class AsyncIndexer

    {

        public static int debugPause;

        Queue<string> urlQueue = new Queue<string>();

        public int QueueSize { get { return urlQueue.Count; } }

        bool busy = false;

        static AsyncIndexer instance = null;

        public static AsyncIndexer GetInstance()

        {

            if (instance == null) instance = new AsyncIndexer();

            return instance;

        }

        delegate void IndexDelegate(Keyoti.SearchEngine.Configuration config);

        public void QueueForIndexing(string documentURL, Keyoti.SearchEngine.Configuration config)

        {

            //add new URL to queue

            urlQueue.Enqueue(documentURL); 

            IndexDelegate indexDelegate = new IndexDelegate(delegate(Keyoti.SearchEngine.Configuration configuration)

            {

                //do indexing work here

                if (!busy)

                {

                    busy = true;

                    //this outer 'while' just takes care of anything added to the queue during the documentIndex.Close() call.

                    while (urlQueue.Count > 0)

                        ProcessQueueItems(configuration);

                    busy = false;

                }               

            });

 

            IAsyncResult ar = indexDelegate.BeginInvoke(config, new AsyncCallback(MyCallback), null);

        }

        void ProcessQueueItems(Keyoti.SearchEngine.Configuration configration)

        {

            Keyoti.SearchEngine.Index.DocumentIndex documentIndex = new Keyoti.SearchEngine.Index.DocumentIndex(configration);

            try

            {

                //while anything is waiting in the queue

                while (urlQueue.Count > 0)

                {

                    documentIndex.AddDocument(new Keyoti.SearchEngine.Documents.Document(urlQueue.Dequeue(), configration));

                    System.Threading.Thread.Sleep(debugPause);

                }

            }

            finally

            {

                documentIndex.Close();

            }

        }

 

        void MyCallback(IAsyncResult ar)

        {

            AsyncResult aResult = (AsyncResult)ar;

            IndexDelegate idxDelegate = (IndexDelegate)aResult.AsyncDelegate;

            idxDelegate.EndInvoke(ar);

        }

    }



2. Use it like this:

AsyncIndexer.GetInstance().QueueForIndexing(documentURL, config);




It should be 'fire and forget' - so you call it, and the ASP.NET page returns immediately. You can get the queue size like this

AsyncIndexer.GetInstance().QueueSize



Here's a complete test example – set the 'debugPause' to allow time for the queue to build up (otherwise it's too quick to test) – it’s currently 7 seconds for each document!

ASPX

<asp:TextBox ID="tb1" runat="server" Width="393px" Text="http://"/>

    <asp:Button ID="indexBt" runat="server" Text="Index Now"

        onclick="indexBt_Click" />

        <asp:Label runat="server" ID="label1"></asp:Label>



CODEBEHIND

 

 

        protected void Page_Load(object sender, EventArgs e)

        {

            AsyncIndexer.debugPause = 7000;

        }

 

        delegate void IndexDelegate(string indexDirectory, Keyoti.SearchEngine.Configuration config);

        protected void indexBt_Click(object sender, EventArgs e)

        {

            string documentURL = tb1.Text;

            Keyoti.SearchEngine.Configuration config = new Keyoti.SearchEngine.Configuration();

            config.IndexDirectory = "c:\\d\\6";

            AsyncIndexer.GetInstance().QueueForIndexing(documentURL, config);

            label1.Text = "Indexing... queue size is " + AsyncIndexer.GetInstance().QueueSize;

        }

 


Related Questions:

Attachments:

No attachments were found.