I had a similar situation when working on an e-commerce platform. Each element had static fields ( Price
, Name
, Category
), which were easily displayed in SOLR schema.xml
, but each element could also have a dynamic number of variations.
For example, a t-shirt in a store may have Color
( Black
, White
, Red
, etc.) and Size
( Small
, Medium
, etc.). attributes, while a candle in the same store may have a Scent
change ( Pumpkin
, Vanilla
, etc.). In essence, this is the relational structure of an entity-attribute database (EAV) used to describe some product features.
Since the schema.xml
file in SOLR is flat in terms of faceting, I worked around it, changing the variations to a single multi-valued field ...
<field name="variation" type="string" indexed="true" stored="true" required="false" multiValued="true" />
... dragging data from the database into these fields as Color|Black
, Size|Small
and Scent|Pumpkin
...
<doc> <field name="id">ITEM-J-WHITE-M</field> <field name="itemgroup.identity">2</field> <field name="name">Original Jock</field> <field name="type">ITEM</field> <field name="variation">Color|White</field> <field name="variation">Size|Medium</field> </doc> <doc> <field name="id">ITEM-J-WHITE-L</field> <field name="itemgroup.identity">2</field> <field name="name">Original Jock</field> <field name="type">ITEM</field> <field name="variation">Color|White</field> <field name="variation">Size|Large</field> </doc> <doc> <field name="id">ITEM-J-WHITE-XL</field> <field name="itemgroup.identity">2</field> <field name="name">Original Jock</field> <field name="type">ITEM</field> <field name="variation">Color|White</field> <field name="variation">Size|Extra Large</field> </doc>
... so when I say SOLR for the brink, I get results that look like ...
<lst name="facet_counts"> <lst name="facet_queries"/> <lst name="facet_fields"> <lst name="variation"> <int name="Color|White">2</int> <int name="Size|Extra Large">2</int> <int name="Size|Large">2</int> <int name="Size|Medium">2</int> <int name="Size|Small">2</int> <int name="Color|Black">1</int> </lst> </lst> <lst name="facet_dates"/> <lst name="facet_ranges"/> </lst>
... so that my code that parses these results for display to the user can just split my delimiter |
(provided that neither my keys nor values will have |
in them), and then are grouped by keys ...
Color White (2) Black (1) Size Extra Large (2) Large (2) Medium (2) Small (2)
... which is good enough for the government to work.
One of the drawbacks of this method is that you will lose the ability to make range faces from this EAV data, but in my case it does not apply (the Price
field applied to all elements and thus defined in schema.xml
so that it can be cut in the usual way).
Hope this helps someone!