Hi guys,
I would like to create products without using the API (The "Product.Save()" method), but still have Lucene index the products when running a "Partial update".
Is it possible to add a created/update product to the lucene queue?
Regards
Martin
Developer forum
E-mail notifications
Mark product as updatet in Lucene when not using Product.Save()
Martin Nielsen
Posted on 17/10/2011 09:07:36
Replies
Pavel Volgarev
Posted on 17/10/2011 10:27:02
Hi Martin,
Yes, it's possible. Here is the code example:
A note regarding "ProductIndexEntry" and parameterless constructor:
There are couple overloads of the constructor (that takes either product ID or product instance) but you should avoid using them for performance reasons. When you pass product ID (as well as variant ID and language ID) the constructor will pull the product from the database but you don't need that because the queue needs only the IDs.
Passing the instance of the product to the constructor will also probably result in some additional database calls (since not all the product information might be available at that time).
For this particular cases we have a static method ProductIndexEntry.CreateQueueEntry that initializes only IDs. The problem with this method is that it's internal. I've changed the access modifier to "public" so the method will be available with the nearest release and you could simply do:
Hope this helps.
-- Pavel
Yes, it's possible. Here is the code example:
using Dynamicweb.Searching; using Dynamicweb.eCommerce; using Dynamicweb.eCommerce.Common; using Dynamicweb.eCommerce.Searching.Index; ...... var productID = "PROD123"; var variantID = "VO1.VO2"; var languageID = "LANG12"; // Getting meta-information about the standard eCommerce product indexer. var info = IndexManager.Current.GetIndexerInfo(typeof(ProductIndexer)); // Getting the instance of the queue that corresponds to our index. var queue = IndexManager.Current.GetIndexerQueue(info.Path); // Creating new index entry. var queueProduct = new ProductIndexEntry(); queueProduct.ID = productID; queueProduct.VariantID = variantID; queueProduct.LanguageID = languageID; // A bit of magic here. // In a later builds you would simply use "ProductIndexEntry.CreateQueueEntry". queueProduct.UniqueID = string.Format("Products!{0}!{1}!{2}", productID, (!string.IsNullOrEmpty(variantID) ? variantID : "0"), (!string.IsNullOrEmpty(languageID) ? languageID : Context.LanguageID)); // Putting the product into the queue (notice that every queue item must be associated with the indexer // that is responsible fo pulling the actual data from the database when the index is being updated). queue.Queue(new IndexerQueueItem(queueProduct, IndexerQueueItemState.Updated), info.ID);
There are couple overloads of the constructor (that takes either product ID or product instance) but you should avoid using them for performance reasons. When you pass product ID (as well as variant ID and language ID) the constructor will pull the product from the database but you don't need that because the queue needs only the IDs.
Passing the instance of the product to the constructor will also probably result in some additional database calls (since not all the product information might be available at that time).
For this particular cases we have a static method ProductIndexEntry.CreateQueueEntry that initializes only IDs. The problem with this method is that it's internal. I've changed the access modifier to "public" so the method will be available with the nearest release and you could simply do:
var queueProduct = ProductIndexEntry.CreateQueueEntry(productID, variantID, languageID);
Hope this helps.
-- Pavel
Martin Nielsen
Posted on 18/10/2011 10:08:56
Great, that looks pretty simple :-)
I'll be looking forward to it becoming a public method.
// Martin
I'll be looking forward to it becoming a public method.
// Martin
Lars Hejgaard Sørensen
Posted on 26/10/2011 09:25:08
Hi Pavel,
I'm also importing products using the API, and I've implemented the suggestions in your post, so my code looks something like this:
using Dynamicweb.Searching; using Dynamicweb.eCommerce; using Dynamicweb.eCommerce.Common; using Dynamicweb.eCommerce.Searching.Index; ...... var info = IndexManager.Current.GetIndexerInfo(typeof(ProductIndexer)); var queue = IndexManager.Current.GetIndexerQueue(info.Path); foreach (var product in collection) var queueProduct = new ProductIndexEntry(); queueProduct.ID = product.ID; queueProduct.VariantID = product.VariantID; queueProduct.LanguageID = product.LanguageID; queueProduct.UniqueID = string.Format("Products!{0}!{1}!{2}", productID, (!string.IsNullOrEmpty(product.VariantID) ? product.VariantID : "0"), (!string.IsNullOrEmpty(product.LanguageID) ? product.LanguageID : Context.LanguageID)); queue.Queue(new IndexerQueueItem(queueProduct, IndexerQueueItemState.Updated), info.ID); } Dynamicweb.Searching.IndexManager.Current.UpdateIndex("Products", false);
The purpose is to have the index updated after all products have been imported, however, apparantly nothing is updated untill I force the update in MGMT center.
Do you have an idea of what's wrong?
BR.
Lars
Pavel Volgarev
Posted on 26/10/2011 09:31:39
Hi Lars,
To trigger the actual update do one of the following:
Synchronous (blocking) call:
Asynchronous (non-blocking) call (not recommended though):
-- Pavel
To trigger the actual update do one of the following:
Synchronous (blocking) call:
Dynamicweb.Searching.IndexManager.Current.UpdateIndex("Products", false);
Dynamicweb.Searching.Management.IndexUpdateService.Current.CreateTask("Products", false);
Pavel Volgarev
Posted on 26/10/2011 09:33:23
Hi Lars,
Sorry, didn't see the last line (where you triggering the update). What the error log says? What about the queue - is it empty after you run the code?
-- Pavel
Sorry, didn't see the last line (where you triggering the update). What the error log says? What about the queue - is it empty after you run the code?
-- Pavel
Lars Hejgaard Sørensen
Posted on 26/10/2011 09:46:43
Hi Pavel,
The server event log is empty. When the import is complete, 933 entries are pending for indexing, but in this case I only updated one product.
BR.
Lars
The server event log is empty. When the import is complete, 933 entries are pending for indexing, but in this case I only updated one product.
BR.
Lars
Pavel Volgarev
Posted on 26/10/2011 09:56:47
Hi Lars,
Could you attach the queue.xml so I can take a look at it (/Files/System/_search/Products/queue.xml)? Also, could you tell the ID of the product that you're updating?
Regarding those 933 items that are currently in the queue. This is probably due to the way the indexer processes the queue file - it doesn't touch (doesn't remove from the queue) those items that it cannot find in the source database. So when you actively manipulate product IDs (through the API) you can end up having the outdated information in your queue...
Anyway, I'd like to see your queue file. And if it's possible, could you provide the URL of the solution so I can log in and find out what's wrong?
-- Pavel
Could you attach the queue.xml so I can take a look at it (/Files/System/_search/Products/queue.xml)? Also, could you tell the ID of the product that you're updating?
Regarding those 933 items that are currently in the queue. This is probably due to the way the indexer processes the queue file - it doesn't touch (doesn't remove from the queue) those items that it cannot find in the source database. So when you actively manipulate product IDs (through the API) you can end up having the outdated information in your queue...
Anyway, I'd like to see your queue file. And if it's possible, could you provide the URL of the solution so I can log in and find out what's wrong?
-- Pavel
Lars Hejgaard Sørensen
Posted on 27/10/2011 11:08:07
Hi Pavel,
I sent you an email with the file.
BR.
Lars
I sent you an email with the file.
BR.
Lars
You must be logged in to post in the forum