在SOLR文档中存储复杂(即标签+ id)元数据

时间:2013-05-20 20:38:59

标签: solr lucene

我使用SOLR来存储具有由多个值组成的元数据的文档。通常是带标签的id。一个简单的例子是城市的名称和该城市的唯一ID。需要身份证,因为不同的城市可以拥有相同的名称,如德国的柏林和美国的柏林。这个名字是显而易见的,因为我想搜索那个字符串。

如果我使用facet,我想回到标有“Berlin”的两个方面。如果我将搜索(使用其他元数据字段)限制为来自德国的文档,我希望德国柏林只能获得一个方面。如果我将id和label存储在两个单独的SOLR字段中,显然这不起作用。

我认为这不是一个不常见的要求,但我无法找到任何有用的信息。我目前的方法是:

  • 在Java中实现完整的自定义字段类型:很难为我估算,因为我目前只是SOLR用户,而不是SOLR开发人员。

  • 将id和label放在一个字符串中(如“123:Berlin”和“456:Berlin”),并使用自定义分析器在schema.xml中定义自定义字段类型,该分析器会对值进行拆分。对我来说听起来很合理,但我不能100%确定它是否适用于刻面。

  • 我发现了一些子字段的引用,但只在较旧的页面上,我找不到有用的文档。

在SOLR中有一些众所周知的解决方法吗?

4 个答案:

答案 0 :(得分:2)

Pivot faceting可以工作。

假设您有字段:cityId, cityName, country

使用查询参数在city-id,city-name上执行数据透视方面:

facet.pivot=cityId,cityName

在第一级,就像标准方面一样,您将获得每个城市ID。但在第二级,您将获得每个城市的名称。鉴于每个城市ID只有一个名称,您只需从下一个方面级别(在XML中的pivot元素下)读取每个城市ID的名称。

<lst name="facet_pivot">
    <arr name="cityId,city">
        <lst>
            <str name="field">cityId</str>
            <str name="value">1</str>
            <int name="count">1</int>
            <arr name="pivot">
                <lst>
                    <str name="field">city</str>
                    <str name="value">berlin</str>
                    <int name="count">1</int>
                </lst>
            </arr>
        </lst>
        <lst>
            <str name="field">cityId</str>
            <str name="value">2</str>
            <int name="count">1</int>
            <arr name="pivot">
                <lst>
                    <str name="field">city</str>
                    <str name="value">berlin</str>
                    <int name="count">1</int>
                </lst>
            </arr>
        </lst>
        <lst>
            <str name="field">cityId</str>
            <str name="value">3</str>
            <int name="count">1</int>
            <arr name="pivot">
                <lst>
                    <str name="field">city</str>
                    <str name="value">melbourne</str>
                    <int name="count">1</int>
                </lst>
            </arr>
        </lst>
    </arr>
</lst>

基本上,如果ID是唯一的,那么您将保证在第二级只有一个pivot值。

或者,如果您想将您的&#39; Berlins&#39;一起,只需颠倒小平面枢轴的顺序并使其成为:

facet.pivot=cityName,cityId

你会得到柏林&#39;在第一级,可能是第二级的多个ID(作为奖励,您可以添加第三级country,以便您可以读取第三级别的每个城市的国家/地区。)

答案 1 :(得分:1)

似乎没有开箱即用的解决方案。

  1. 您的#2应该可以正常运行一些客户端修改。
  2. 您可以使用id_name将数据编入索引作为单个字符串字段。需要 在索引时改变。如果您正在使用变形金刚,则更容易使用 DIH。
  3. 您现在可以为每个ID和客户端提供唯一的方面 您可以随时拆分Facets进行显示。
  4. 您还可以查看Facet Pivots,它可以提供Hierarchical Faceting

答案 2 :(得分:0)

那应该有用。如果您添加过滤器查询(例如fq=country_name:Germany),则应仅返回德国城市的构面。请看下面这个例子:

假设您的架构中有4个字段:

id,city_name,country_name,state_name

示例数据:

id: 1

city_name:柏林

country_name:德国

state_name: Some_State1


id: 2

city_name:柏林

country_name:美国

state_name: Some_State2


id: 3

city_name:都柏林

country_name:爱尔兰

state_name: Some_State3


id: 4

city_name:都柏林

country_name:美国

state_name:加利福尼亚州


id: 5

city_name:都柏林

country_name:美国

state_name:弗吉尼亚州


如果你想获得名为都柏林的所有城市的方面:

/select/?q=*:*&facet=true&facet.field=country_name&facet.field=city_name&fq=city_name:Dublin

在结果中,都柏林方面的计数将为3


现在,如果您希望所有名为Dublin的城市都有方面,并将国家/地区限制为美国,那么您的查询将是:

/select/?q=*:*&facet=true&facet.field=country_name&facet.field=city_name&fq=city_name:Dublin&fq=country_name:USA

在结果中,都柏林方面的计数将为2,因为我们在美国有两个Dublins,一个在加利福尼亚州,另一个在弗吉尼亚州

注意:我添加了&amp; fq = country_name:USA

答案 3 :(得分:0)

一个相当简单的建议:在索引时通过copyField使用两个字段来表示“123:Berlin”等值

一个 indexedstored字符串字段,用于在客户端进行分面加解析/清理 对于搜索,请使用简单的正则表达式分析器(indexed)复制一个stored而不是PatternReplaceCharFilterFactory

不需要自定义分析器或新类型的字段,就像您在第二个解决方案中已经指出的那样