Solr

时间:2015-05-05 13:12:29

标签: solr faceted-search hierarchical

问题

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

到目前为止我的研究

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

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

示例(概念上)

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

TESTDATA

输入

假设我们有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

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

<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

Solr statistics page

第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查询( with faceting)

检索所有数据

查询

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,因为它仅设置为Alice,而Bob的{​​{1}}和Norway未汇总,也计入Sweden

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

版本

  • Solr 5.1.0
  • Windows 7

1 个答案:

答案 0 :(得分:4)

如果您将这些聚合分阶段推入索引,则可以填充所有聚合。如果Bob来自挪威,您可以在facet字段中填充最多三个值:

location
location/Europe
location/Europe/Norway

(作为替代设计,您可能会将头发颜色字段与位置字段分开,然后&#34;位置&#34;永远不需要在字段本身中填充。)

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

避免在Solr facet字段中添加重复条目的另一个有点风险的选项是仅添加您现在使用的值(例如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&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实际上并不知道挪威在欧洲,巴西在南美洲,所以你将开始获得欧洲&gt;欧洲&gt;巴西&#34;并且对于&#34;南美洲&gt;挪威&#34;

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

<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>

通过这种方式,您仍然可以获得不匹配的数据透视值,但您可以选择阻止任何不具有与其大陆匹配的前缀的国家/地级级别值。如果这是一个问题,则数据透视中的多值字段必须具有与在同一个数据透视中显示以后的值相关联的值。如果您不希望单个记录中的这些字段具有多个值,或者您的值没有强关联(即特定的父级),则数据透视方面可能是理想的解决方案。但在某些情况下,枢轴方面在所包含字段中的值之间的分离可能会造成严重的混乱。