Can I search/index a custom datasource in Orchard via Lucene?
Asked Answered
E

1

6

I am currently working on a site to allow users to search through a custom product catalog. I have been looking around and would love to leverage Orchard CMS to help me develop this site. I have currently gone through Ron Petersons youtube series on custom Orchard Modules and the Skywalker blog series.

I feel like my goal is possible, but I'm looking for some validation on whether my strategy will work within the Orchard framework.

This is my current situation:

  1. I have an default Orchard configuration pointing to a SQL DB (named Product-Orchard)

  2. I have a custom DAL that points to another SQL DB (named Products).

  3. Products are made up of your typical information (Product Name, Description, Price, etc).

  4. The custom DAL has a POCO model called Product (with a Repository to interact with) with the properties Name, Description, Price.

Now, based on the information I read about creating Orchard modules it seems like the method of creating a custom module with custom content is to:

  1. Create a Module through code gen tools (We'll call it ProductModule)

  2. Create a custom Content Part (ProductPart)

  3. Create a custom Content Part Record (ProductPartRecord) to act as the data model for the part.

  4. Create a custom ContentPartHandler (ProductPartHandler) that handles the persistance of the Content Part.

  5. Create a custom Driver that is the entry for preparing the Shapes for rendering of the UI.

  6. Potentially create a Service that interacts with the Drivers?

This is where things start to get jumbled and I'm not sure if this is possible or not. What I would like to do is to create a custom Content Type that is backed by my custom DAL rather than having the data be stored through the ContentPartRecord inside the Product-Orchard DB, but still allow it to be indexed by the Lucene module to allow for searching of the Product catalog.

Is it possible to create a custom ContentType and/or ContentPart that is backed by a different datasource and still leverage the Lucene search capabilities?

In high level terms I'd like a Product ContentType where the ContentItems are actually stored in my secondary database, not the Orchard database (and still want to be able to leverage Lucene search via Projections).

Emprise answered 12/8, 2013 at 14:53 Comment(5)
Are you looking to convert your products into content items?Cycling
I would like to be able to just read from the product catalog directly, but if that is not feasible, then yes I could convert. Each Product has about 12 properties, but I only need to be able to search on 3 or 4 of them. One option I am toying with is I could create a custom ProductPart with those searchable properties. Then when I need all the information (like on the Product details page) I would do something like this: #4728343.Emprise
This would require me to have a sync process to sync data from the product catalog to the Orchard db, which I'd like to avoid, but if that is the best method I could do that.Emprise
Well you would have to create content items for all your products, and I suppose you could link to your remote source each time you display an item and expose those fields when you are indexing. Sounds feasible, although I have never really used the indexing api I'm afraid. But I would say that it would be cleaner to convert your products into actual content items. Maybe. ^_^Cycling
You can tell the indexer what fields you want indexed in the handler for that specific content part. The issue I've had in the past with this is I can't create a content part with fields that aren't created in the database. NHibernate looks for those columns that don't exist and eventually I have to create them using the migrations class.Dulcle
E
7

For those searching for a similar answer, the following solution is what I settled on. There is no easy mechanism I could find to interact with a separate DAL and perform the Lucene indexing.

  1. Create the Orchard Module
  2. Create new Content Part/Type via aMigration
  3. Use Orchard Command infrastructure to import data from your secondary database
  4. Use the OnIndexing event in the Content Part handler to allow Lucene to index your datasource.
  5. Create a lookup property (I called mine ConcreateProperty) that is populated through a Service I created in the module to interact with the secondary DAL in the OnLoaded event.

My final Handler looked like this:

public class HomePartHandler : ContentHandler {
    public HomePartHandler(IRepository<HomePartRecord> repository, IHomeSearchMLSService homeSearchService) {
        Filters.Add(StorageFilter.For(repository));
        OnLoaded<HomePart>((ctx, part) =>
        {
            part.ConcreteProperty = homeSearchService.GetByMlsNumber(part.MlsId) ?? new PropertyDetail();
        });
        OnIndexing<HomePart>((context, homePart) => context.DocumentIndex
         .Add("home_StreetFullName", homePart.Record.StreetFullName).RemoveTags().Analyze().Store()
         .Add("home_City", homePart.Record.City).RemoveTags().Analyze().Store()
         .Add("home_State", homePart.Record.State).RemoveTags().Analyze().Store()
         .Add("home_Zip", homePart.Record.Zip).RemoveTags().Analyze().Store()
         .Add("home_Subdivision", homePart.Record.Subdivision).RemoveTags().Analyze().Store()
         .Add("home_Beds", homePart.Record.Beds).RemoveTags().Analyze().Store()
         .Add("home_Baths", homePart.Record.Baths).RemoveTags().Analyze().Store()
         .Add("home_SquareFoot", homePart.Record.SquareFoot).RemoveTags().Analyze().Store()
         .Add("home_PropertyType", homePart.Record.PropertyType).RemoveTags().Analyze().Store()
         .Add("home_ListPrice", homePart.Record.ListPrice).RemoveTags().Analyze().Store()
         .Add("home_MlsId", homePart.Record.MlsId).RemoveTags().Analyze().Store()
         .Add("home_Latitude", (double)homePart.Record.Latitude).RemoveTags().Analyze().Store()
         .Add("home_Longitude", (double)homePart.Record.Longitude).RemoveTags().Analyze().Store()
          );
    }
}

This allows me to create a search service for searching through all my data and then hook it up to the model via the Concrete Property, which actually works better from a performance standpoint anyway.

Emprise answered 30/8, 2013 at 16:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.