【问题标题】:Solr supporting varying facets for different types of productsSolr 支持不同类型产品的不同方面
【发布时间】:2015-03-02 23:53:34
【问题描述】:

我正在使用 Solr 来索引不同类型的产品。产品类型(类别)具有不同的方面。例如:

camera: megapixel, type (slr/..), body construction, ..
processors: no. of cores, socket type, speed, type (core i5/7)
food: type, origin, shelf-life, weight
tea: type (black/green/white/..), origin, weight, use milk?
serveware: type, material, color, weight
...

它们也有共同点:

Brand, Price, Discount, Listing timeframe (like new), Availability, Category

当用户点击任何类别、品牌页面或对所有类型的产品进行全局搜索时,我需要显示相关方面和面包屑。这与我们在几个电子商务网站上看到的相同。

我的查询是: 由于构面类型在不同类型的产品中或多或少是唯一的,我是否将它们放在单独的模式中?这是这样做的方法吗?根本的担忧是这些字段将没有其他类型产品的任何数据。这里是否有任何实现原则可以更轻松地检索给定产品类型的相应面孔?

我希望有一个可扩展的设计,以便在我们前进的过程中容纳每种产品类型中的大量项目,并且尽可能易于使用和以性能为导向。现在我只有一个 Solr 实例。

【问题讨论】:

  • 应该不需要设置多个 Solr 实例,但实现部分取决于您是否提前知道用户在哪个类别中搜索。无论哪种方式,这都应该可以在单个 Solr 索引中进行管理,但是如果您知道这一点,那么实现将更加高效和简单。
  • 不管那个问题,知道solrconfig.xml 包含查询时间信息可能会有所帮助,因此可以在不重新索引的情况下进行更改,并且它可能包含单个 Solr 索引的多个请求处理程序.您可以在 solrconfig.xml 的请求处理程序或查询 url 本身中配置分面选项。您可以在查询时确定您感兴趣的构面,只要所有可能的构面字段都被索引(由schema.xml 确定)用于构面,这意味着同时具有indexed="true" 和stored="true"。
  • @frances 感谢您的 cmets。所以你是说一个单一的 schema.xml,有 n 个 facet 字段,但大部分没有填充(基于产品类型和它们的 facet)绝对是一个被接受的设计?
  • @frances 我想我会知道搜索的类别。如果是全局搜索(搜索字段中的用户字符串),那么 solr 将返回每个产品的索引类别,但这可能是唯一我不会提前知道的情况。对于其他人,例如品牌页面、产品类别页面(来自菜单),我将事先获得类别信息。

标签: solr facet faceted-search


【解决方案1】:

方面填充不足的唯一风险是它们歪曲了搜索。我确定您使用了一个搜索站点,在该站点上,您想要分面的元数据填充不足,因此当您应用分面时,您还会从结果集中消除许多应该包含的记录。需要注意的是,在适当的地方一致地填充构面值。这意味着您的“茶”记录不需要列出多个核心,并且不会影响任何事情,但是您的所有“处理器”记录都应该,并且(在任何可能的范围内)应该一致地填充它们.这意味着,如果一个处理器将其内核数列为“4”,而另一个处理器显示“四核”,则这是两个不同的值,用户应用任一方面值都会从其结果中消除另一个处理器。如果第三个四核处理器完全缺少 no_cores 方面字段中的“核心数”统计信息(字段名称是任意的),那么您的方面可能会适得其反。

因此,我们可以将所有这些记录放入同一个 Solr 中,只要在适当的情况下一致地填充构面,就不必为所有记录填充它们,尤其是在不适用时。

动态应用构面

您需要了解的大部分内容都在 Solr 的 faceting 文档中。重要的是在查询中指定适当的参数以告诉 Solr 您要使用哪些方面。 (直到您实际对一个字段进行分面,它才不是一个分面,而只是一个同时是stored="true" 和indexed="true" 的字段。)为了获得非常动态的效果,您可以将所有这些参数指定为对Solr 的查询的一部分。

&facet=true

这似乎很明显,但您需要打开分面。这个参数很方便,因为它还允许您使用facet=false关闭分面,即使您的查询中有很多其他参数详细说明如何分面。如果 faceting 关闭,它什么都不会做。

&facet.field=no_cores

您可以反复添加此字段,以获取您对分面感兴趣的多个字段。

&facet.limit=7
&f.no_cores.facet.limit=4

此处的第一行将 Solr 为每个构面字段返回的值的数量限制为 7。将返回构面最频繁的 7 个值(在搜索结果中),以及它们的记录计数。第二行专门覆盖了 no_cores 字段的此限制。

&facet.sort=count

您可以按出现在多少记录中的顺序 (count) 或按索引顺序 (index) 列出构面字段的值。索引顺序通常表示按字母顺序,但取决于字段的索引方式。此字段与facet.limit 一起使用,因此如果返回的构面值的数量受facet.limit 的限制,它们将是结果集中最多的值或索引中最早的值,具体取决于如何设置此值.

&facet.mincount=1

在极少数情况下,您会希望看到在搜索结果中出现零次的构面值,如果它弹出,这可以解决问题。

最终结果是一个很长的查询:

http://localhost/solr/collecion1/search?facet=true&facet.field=no_cores&
 facet.field=socket_type&facet.field=processor_type&facet.field=speed&
 facet.limit=7&f.no_cores.facet.limit=4&facet.mincount=1&defType=dismax&
 qf=name,+manufacturer,+no_cores,+description&
 fl=id,name,no_cores,description,price,shipment_mode&q="Intel"

这绝对是有效的,并且允许对搜索应该如何工作进行最大程度的即时决策,但对于调试来说不是很可读。

不那么动态地应用构面

因此,这些功能允许您指定要分面的字段,并动态执行此操作。但是,它可能会导致大量非常长且复杂的查询,尤其是当您在几种不同的搜索模式中使用大量方面时。

一个选项是在您的solrconfig.xml 中的请求处理程序中将每组常用选项形式化。这样,您可以应用完全相同的参数,但无需在每个查询中列出所有参数,您只需指定所需的请求处理程序即可。

<requestHandler name="/processors" class="solr.SearchHandler">
 <lst name="defaults">
  <str name="defType">dismax</str>
  <str name="echoParams">explicit</str>
  <str name="fl">id,name,no_cores,description,price,shipment_mode</str>
  <str name="qf">name, manufacturer, no_cores, description</str>
  <str name="sort">score desc</str>
  <str name="rows">30</str>
  <str name="wt">xml</str>
  <str name="q.alt">*</str>
  <str name="facet.mincount">1</str>
  <str name="facet.field">no_cores</str>
  <str name="facet.field">socket_type</str>
  <str name="facet.field">processor_type</str>
  <str name="facet.field">speed</str>
  <str name="facet.limit">10</str>
  <str name="facet.sort">count</str>
 </lst>
 <lst name="appends">
  <str name="fq">category:processor</str>
 </lst>
</requestHandler>

如果您在solrconfig.xml 中设置了一个请求处理程序,它所做的只是作为一组查询参数的简写。对于单个 solr 索引,您可以拥有任意数量的请求处理程序,并且您可以在不重建索引的情况下更改它们(重新加载 Solr 核心或重新启动服务器应用程序(例如 JBoss 或 Tomcat),以使更改生效)。

这个请求处理程序有很多我没有涉及的事情,但这只是表示默认 Solr 请求参数的一种方式,以便您的实时查询可以更简单。这样,您可能会进行如下查询:

http://localhost/solr/collection1/processors?q="Intel"

返回一个结果集,其中填充了所有特定于处理器的方面,并进行过滤,以便只返回处理器记录。 (这是category:processor 过滤器,它假定一个名为category 的字段,其中所有处理器记录都有一个值processor。这完全是可选的,取决于您。)您可能希望保留默认的搜索请求处理程序不按记录类别过滤,并且可能不会选择将任何可用(stored="true" 和 indexed="true")字段作为活动构面应用。

【讨论】:

  • 非常感谢您的描述性回答。将通过它,让你知道我是否需要任何澄清。与此同时,我也一直在探索这一点。我遇到了使用 dynamicField 的要点,重用预定义字段的机会以及枢轴和相关面包屑的概念。我一直在阅读的一个有趣的文档:rhizomik.net/html/~roberto/papers/… 和 lucene.472066.n3.nabble.com/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-21
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多