【问题标题】:Hierarchical faceted search example with SolrSolr 的分层分面搜索示例
【发布时间】:2015-07-15 05:57:13
【问题描述】:

问题

我在哪里可以找到一个完整的示例来展示分层分面搜索如何从索引文档到检索搜索结果?

到目前为止我的研究

Stackoverflow 有一些帖子,但它们都只涉及分层分面搜索的某些方面;因此,我不会认为它们是重复的。我正在寻找一个完整的例子来理解它。我一直错过聚合工作的最后一个查询。

Solr 网页上有文档,但不理解那里给出的示例。

示例(概念上)

我想在这里创建一个完整的演练示例,并希望您能提供缺少的最终部分。

测试数据

输入

假设我们有 3 个文档,每个文档都是一个人。

Alice (document 1)
 - Blond
 - Europe

Jane (document 2)
 - Brown
 - Europe/Norway

Bob (document 3)
 - Brown
 - Europe/Norway
 - Europe/Sweden

输出

此(当前错误)查询的预期输出

http://server:8983/solr/my_core/select?q=*%3A*&wt=json&indent=true&facet=true&facet.field=tags_ss

应该是

Hair_color (3)
- blond (1)
- brown (1)
- black (1)

Location (3)
- Europe (4)  // This should be 4 not 3, i.e. the sum of the leaves, because Alice is tagged with "Europe" only, without a country
  - Norway (2)
  - Sweden (1)

因为所有文档都找到了。

示例(以编程方式)

这是我需要帮助的地方。如何实现上述概念性示例?

这是我已经走了多远。

1.创建测试数据 XML

这是solr-5.1.0/testdata 子文件夹中documents.xml 文件的内容:

<add>
    <doc>
        <field name="id">Alice</field>
        <field name="tags_ss">hair_color/blond</field>
        <field name="tags_ss">location/Europe</field>
    </doc>
    <doc>
        <field name="id">Jane</field>
        <field name="tags_ss">hair_color/brown</field>
        <field name="tags_ss">location/Europe/Norway</field>
    </doc>
    <doc>
        <field name="id">Bob</field>
        <field name="tags_ss">hair_color/black</field>
        <field name="tags_ss">location/Europe/Norway</field>
        <field name="tags_ss">location/Europe/Sweden</field>
    </doc>
</add>

_ssschema.xml 中定义为

<dynamicField name="*_ss" type="string"  indexed="true"  stored="true" multiValued="true"/>

请注意,所有标签,例如hair_color location 以及将来添加的任何标签都存储在同一个tags_ss 字段中。

2。用 Solr 索引测试数据

c:\solr-5.1.0>java -classpath dist/solr-core-5.1.0.jar -Dauto=yes -Dc=gettingstarted -Ddata=files -Drecursive=yes -Durl=http://server:8983/solr/my_core/update org.apache.solr.util.SimplePostTool .\testdata

3.使用 Solr 查询检索所有数据(没有分面)

查询

http://server:8983/solr/my_core/select?q=*%3A*&wt=json&indent=true

结果

{
  "responseHeader": {
    "status": 0,
    "QTime": 0,
    "params": {
      "indent": "true",
      "q": "*:*",
      "_": "1430830360536",
      "wt": "json"
    }
  },
  "response": {
    "numFound": 3,
    "start": 0,
    "docs": [
      {
        "id": "Alice",
        "tags_ss": [
          "hair_color/blond",
          "location/europe"
        ],
        "_version_": 1500334369469890600
      },
      {
        "id": "Jane",
        "tags_ss": [
          "hair_color/brown",
          "location/europe/Norway"
        ],
        "_version_": 1500334369469890600
      },
      {
        "id": "Bob",
        "tags_ss": [
          "hair_color/black",
          "location/europe/Norway",
          "location/europe/Sweden"
        ],
        "_version_": 1500334369469890600
      }
    ]
  }
}

4.使用 Solr 查询检索所有数据(带有分面)

查询

http://server:8983/solr/my_core/select?q=*%3A*&wt=json&indent=true&facet=true&facet.field=tags_ss

结果

{
  "responseHeader": {
    "status": 0,
    "QTime": 0,
    "params": {
      "facet": "true",
      "indent": "true",
      "q": "*:*",
      "_": "1430830432389",
      "facet.field": "tags_ss",
      "wt": "json"
    }
  },
  "response": {
    "numFound": 3,
    "start": 0,
    "docs": [
      {
        "id": "Alice",
        "tags_ss": [
          "hair_color/blond",
          "location/europe"
        ],
        "_version_": 1500334369469890600
      },
      {
        "id": "Jane",
        "tags_ss": [
          "hair_color/brown",
          "location/europe/Norway"
        ],
        "_version_": 1500334369469890600
      },
      {
        "id": "Bob",
        "tags_ss": [
          "hair_color/black",
          "location/europe/Norway",
          "location/europe/Sweden"
        ],
        "_version_": 1500334369469890600
      }
    ]
  },
  "facet_counts": {
    "facet_queries": {},
    "facet_fields": {
      "tags_ss": [
        "location/europe/Norway",
        2,
        "hair_color/black",
        1,
        "hair_color/blond",
        1,
        "hair_color/brown",
        1,
        "location/europe",
        1,
        "location/europe/Sweden",
        1
      ]
    },
    "facet_dates": {},
    "facet_ranges": {},
    "facet_intervals": {},
    "facet_heatmaps": {}
  }
}

请注意结果底部的此部分:

"facet_fields": {
  "tags_ss": [
    "location/europe/Norway",
    2,
    "hair_color/black",
    1,
    "hair_color/blond",
    1,
    "hair_color/brown",
    1,
    "location/europe",
    1,
    "location/europe/Sweden",
    1
  ]
},

它将所有标签显示为一个平面列表(不是分层的)。

5.使用 Solr 查询检索所有数据(使用分层分面)

查询

这是我的问题。我不知道如何构造返回以下结果的查询(结果已经在上面的概念示例中显示)。

结果(虚构,为说明而手工制作)

{
  "responseHeader":{
    "status":0,
    "QTime":0,
    "params":{
      "facet":"true",
      "indent":"true",
      "q":"*:*",
      "facet.field":"tags_ss",
      "wt":"json",
      "rows":"0"}},
  "response":{"numFound":3,"start":0,"docs":[]
  },
  "facet_counts":{
    "facet_queries":{},
    "facet_fields":{
      "tags_ss":[
        "hair_color,3, // This aggregations is missing
        "hair_color/black",1,
        "hair_color/blond",1,
        "hair_color/brown",1,
        "location/europe",4, // This aggregation should be 4 but is 1
        "location/europe/Norway",2,
        "location/europe/Sweden",1]},
    "facet_dates":{},
    "facet_ranges":{},
    "facet_intervals":{},
    "facet_heatmaps":{}}}

这个标签列表仍然是扁平的,但至少location/europe = 4 会被正确聚合,但目前不是。我不断收到location/europe = 1,因为它只设置为AliceBobNorwaySweden 没有汇总到Europe

想法

  • 我可能需要使用facet.pivot,但我不知道如何使用。
  • 我可能需要使用facet.prefix,但我不知道如何使用。

版本

  • Solr 5.1.0
  • Windows 7

【问题讨论】:

    标签: solr faceted-search hierarchical


    【解决方案1】:

    如果您分阶段将它们推送到索引中,则可以填充所有聚合。如果 Bob 来自挪威,您最多可以在构面字段中填充三个值:

    location
    location/Europe
    location/Europe/Norway
    

    (作为替代设计,您可能有一个与位置字段分开的头发颜色字段,然后永远不需要在字段本身中填充“位置”。)

    那么你的结果仍然是平的,但你的总和是存在的。此时,您将需要对结果集进行一些编程工作,以创建一个嵌套数据结构,该结构通过拆分分隔符上的所有值(在本例中为/)构建。一旦你有一个嵌套的数据结构,那么分层显示它应该是可管理的。很难详细介绍这部分实现,因为您的嵌套数据结构和显示将在很大程度上取决于您的开发环境。

    避免在 Solr 构面字段中添加重复条目的另一个有点冒险的选择是仅添加您现在使用的值(例如 location/Europe/Norway),但在您遍历构面列表时将叶总数相加并构建您的嵌套数据结构。存在的风险是,如果一个人真正与欧洲的多个国家/地区相关联,那么您可能会得到更高级别的夸大总数location/Europe。如上所述,我已在自己的项目中选择填充单独的值。尽管它们看起来多余,但总和最终会更准确。

    (与 Solr 中的往常一样,这只是众多处理方式中的一种。此模型最适用于总叶子数可控的系统,在这种情况下,预先检索所有构面值并不必进行额外的深入查询。)

    旋转选项

    Solr facet pivoting 可以直接从 Solr 返回分层结构的结果,但在某些情况下存在在值之间创建错误连接的风险。

    所以,假设您像这样加载文档:

    <add>
     <doc>
      <field name="id">Alice</field>
      <field name="continent">Europe</field>
     </doc>
     <doc>
      <field name="id">Jane</field>
      <field name="continent">Europe</field>
      <field name="country">Norway</field>
     </doc>
     <doc>
      <field name="id">Bob</field>
      <field name="continent">Europe</field>
      <field name="country">Norway</field>
      <field name="country">Sweden</field>
     </doc>
    </add>
    

    现在您使用facet.pivot.mincount=1&amp;facet.pivot=continent,country 执行分面数据透视查询。到目前为止,结果可能很好:

    "facet_pivot":{
     "continent,country":[{
      "field":"continent",
      "value":"Europe",
      "count":3,
      "pivot":[{
        "field":"country",
        "value":"Norway",
        "count":2,},
          {
        "field":"country",
        "value":"Sweden",
        "count":1,}]}]}
    

    到目前为止一切顺利。当您向数据中添加一个新人时,问题就来了:

    <add>
     <doc>
      <field name="id">Susan</field>
      <field name="continent">Europe</field>
      <field name="country">Norway</field>
      <field name="continent">South America</field
      <field name="country">Brazil</field>
     </doc>
    </add>
    

    现在 Solr 实际上并不知道挪威在欧洲而巴西在南美,因此您将开始获得“欧洲 > 巴西”和“南美 > 挪威”的构面计数。

    如果您将大陆前缀添加到您的所有国家/地区值,则问题是可以解决的:

    <add>
     <doc>
      <field name="id">Susan</field>
      <field name="continent">Europe</field>
      <field name="country">Europe/Norway</field>
      <field name="continent">South America</field
      <field name="country">South America/Brazil</field>
     </doc>
    </add>
    

    这样您仍然会得到不匹配的数据透视值,但您可以选择阻止任何没有与其大陆匹配的前缀的国家级构面值。为了成为一个问题,透视中的 multivalued 字段必须具有与同一透视中稍后出现的值相关联的值。如果您不希望在单个记录中为这些字段提供多个值,或者如果您的值没有强关联(即特定的出身),则枢轴分面可能是一个理想的解决方案。但在某些情况下,枢轴分面在所包含字段中的值之间的分离可能会造成令人望而却步的混乱。

    【讨论】:

    • 谢谢。只是为了澄清:这是否意味着如果我只用location/europe/Norway 填充Bobtag_ss 字段而不是三个值locationlocation/Europelocation/Europe/Norway 如你所建议的那样,Solr 是 不能 将其拆分和聚合?它是否正确?我本来希望不是这样的;我本来希望 Solr 能为我完成这项工作。
    • 它可以通过枢轴刻面做到这一点,但并非没有警告。在评论中解释太多了,所以我编辑了我的答案。
    • 我还注意到,在您的问题中,您多次表示欧洲的总计数应该是 4。我在第一遍时并没有真正考虑过这一点,但重要的是要注意 Solr刻面计数始终计算匹配的记录,而不是匹配的字段。无论一条记录引用欧洲多少次,它都不会超过一次。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多