Solr Sort Hybris

问题描述 投票:0回答:1

我有一个提供商,它可以为每个单位的产品库存编制索引,这样:

for (Map.Entry<B2BUnitModel, Integer> unit : stockByUnit.entrySet() )
    {
        document.addField(indexedProperty, hasStock(unit.getValue()), unitUid(unit.getKey()));
    }

所以这是 solr 中索引后的结果:

"localStockForUnt_001_boolean": true,
"localStockForUnt_002_boolean": true,

其中 localStockForUnt 是 SolrIndexedProperty,001 和 002 是单位,true 或 false 是索引值。

这是创建它的关键:

INSERT_UPDATE SolrIndexedProperty;solrIndexedType(identifier)`[unique=true];name[unique=true];type(code);sortableType(code);currency[default=false];localized[default=false];multiValue[default=false];useForSpellchecking[default=false];useForAutocomplete[default=false];fieldValueProvider;valueProviderParameter`
;$solrIndexedType; localStockForUnt       ;boolean ;            ;    ;    ;    ;     ;   ;myResolver;

所以我将它添加到 hmc 中名为“相关性”的“排序”中,这个“排序”在 hmc 中只有这个字段。

我的疑问是,如何设置它使用 localStockForUnt_002_boolean 等对结果进行排序? 我确实在控制器中手动设置了排序来测试,我确实将其设置为“相关性”,但是由于相关性中使用的字段提供者(localStockForUnt)索引了两个不同的信息,我如何选择使用哪一个?

sorting solr sap-commerce-cloud
1个回答
2
投票

实际上你在这里尝试做的事情已经被 Hybris 发起并在几个案例中使用过,例如:

  • localized
    属性,例如
    name
    ,索引为
    name_en_string
  • 带有
    currency
    (如
    price
    )的属性被索引为
    priceValue_eur_double
    ,也用于排序。

对于

priceValue_eur_double
      |    对于
localStockForUnt_001_boolean

priceValue
是字段名称    |   
localStockForUnt
是字段名称。
eur
是字段限定符    |   
001
是字段限定符。
double
是字段类型    |   
boolean
是字段类型。

所以你这里的情况与这两个例子没有什么不同,因此你只需要知道如何使用已经存在的东西。

实际上这两个示例的工作原理并没有什么神奇之处!

  1. 首先,添加新的布尔值
    attribute
    SolrIndexedPropertyModel
    我们称之为
    isB2bUnit
    :
<!-- add this to your *-items.xml -->
<itemtype code="SolrIndexedProperty" autocreate="false" generate="false">
    <attributes>

        <attribute qualifier="isB2bUnit" type="java.lang.boolean">
            <persistence type="property" />
            <!-- i would prefer to add a default value here : FALSE -->
        </attribute>

    </attributes>
</itemtype>
  1. 接下来你必须在
    boolean attribute
    dto 中添加相同的
    IndexedProperty
    :
<!-- add this to your *-beans.xml -->
<bean class="de.hybris.platform.solrfacetsearch.config.IndexedProperty">

    <property name="isB2bUnit" type="boolean"/>     

</bean>
  1. 然后你需要覆盖
    DefaultIndexedPropertyPopulator
    ,它负责从
    SolrIndexedProperty
    转换为
    IndexedProperty
public class MyIndexedPropertyPopulator extends DefaultIndexedPropertyPopulator {

    @Override
    public void populate(SolrIndexedPropertyModel source, IndexedProperty target) throws ConversionException {

        super.populate(source, target);

        //add this line
        target.setIsB2bUnit(source.getIsB2bUnit());

    }

}

propulator
注册到 spring 中。

<!-- add this to your *-spring.xml -->

<alias name="myIndexedPropertyPopulator" alias="indexedPropertyPopulator" />

<bean id="myIndexedPropertyPopulator" class="com.foo.bar.MyIndexedPropertyPopulator" parent="defaultIndexedPropertyPopulator" />
  1. 这个想法是挂钩此方法
    DefaultFieldNameTranslator.translateFromProperty(...)
    ,并强制它将您的特定
    fieldQualifier
    (即
    b2bUnit.code
    )添加到
    fieldName
    (如果
    isB2bUnit
    Indexedproperty
    TRUE
    )。

原来的

DefaultFieldNameTranslator.translateFromProperty(...)
是这样的:

protected String translateFromProperty(SearchQuery searchQuery, IndexedProperty indexedProperty, FieldType fieldType) {

    //...

    if(qualifierProvider != null && qualifierProvider.canApply(indexedProperty)) {

        Qualifier qualifier = qualifierProvider.getCurrentQualifier();
        fieldQualifier = qualifier != null?qualifier.toFieldQualifier():null;

    } else if(indexedProperty.isLocalized()) {

        fieldQualifier = searchQuery.getLanguage();

    } else if(indexedProperty.isCurrency()) {

        fieldQualifier = searchQuery.getCurrency();

    }

    //you have to add your else if here!!!

    return this.fieldNameProvider.getFieldName(indexedProperty, fieldQualifier, fieldType);

}

因此创建从

MyFieldNameTranslator
延伸的
DefaultFieldNameTranslator
并覆盖
translateFromProperty(...)

注意:

SomeB2bUnitService
这个服务不是真实的,但它应该能够返回当前的b2bUnit。

public class MyFieldNameTranslator extends DefaultFieldNameTranslator {

    //To be injected!!
    private SomeB2bUnitService someB2bUnitService;

    @Override
    protected String translateFromProperty(SearchQuery searchQuery, IndexedProperty indexedProperty, FieldType fieldType) {

        //...

        //...

        else if(indexedProperty.getIsB2bUnit()) {

            fieldQualifier = someB2bUnitService.getCurrentB2bUnit().getCode();

        }

        return this.fieldNameProvider.getFieldName(indexedProperty, fieldQualifier, fieldType);

    }

}

Translator
注册到
Spring
:

<!-- add this to your *-spring.xml -->

<alias name="myfieldNameTranslator" alias="fieldNameTranslator" />

<bean id="myfieldNameTranslator" class="com.foo.bar.MyFieldNameTranslator" parent="defaultfieldNameTranslator">

    <property name="someB2bUnitService" ref="someB2bUnitService" />

</bean>
  1. 编辑:现在您所要做的就是将
    isB2bUnit
    设置为
    true
    localStockForUnt
    :
INSERT_UPDATE SolrIndexedProperty;solrIndexedType(identifier)[unique=true] ;name[unique=true] ;type(code) ;isB2bUnit
;$solrIndexedType ;localStockForUnt  ;boolean  ;true

注意:一些类和 bean 可能在 Hybris 版本之间发生了变化,但概念保持不变。

© www.soinside.com 2019 - 2024. All rights reserved.