如何在 Broadleaf REST 中进行过滤和排序?

How to do filter and sort in Broadleaf REST?

在 broadleaf 中,搜索是使用 solr 完成的。我能够正确搜索。我才知道过滤和排序也是solr做的,所以我想知道这两者是如何实现的?

我发现过滤和排序使用了搜索方面,我执行了以下几行:

INSERT INTO BLC_FIELD (FIELD_ID, ENTITY_TYPE, PROPERTY_NAME, ABBREVIATION, SEARCHABLE, FACET_FIELD_TYPE) VALUES (1, 'PRODUCT', 'manufacturer', 'mfg', TRUE, 's');
INSERT INTO BLC_FIELD (FIELD_ID, ENTITY_TYPE, PROPERTY_NAME, ABBREVIATION, SEARCHABLE, FACET_FIELD_TYPE) VALUES (2, 'PRODUCT', 'defaultSku.retailPrice', 'price', FALSE, 'p');
INSERT INTO BLC_FIELD (FIELD_ID, ENTITY_TYPE, PROPERTY_NAME, ABBREVIATION, SEARCHABLE, TRANSLATABLE, FACET_FIELD_TYPE) VALUES (3, 'PRODUCT', 'defaultSku.name', 'name', TRUE, TRUE, 's');
INSERT INTO BLC_FIELD (FIELD_ID, ENTITY_TYPE, PROPERTY_NAME, ABBREVIATION, SEARCHABLE, FACET_FIELD_TYPE) VALUES (4, 'PRODUCT', 'model', 'model', TRUE, 's');
INSERT INTO BLC_FIELD (FIELD_ID, ENTITY_TYPE, PROPERTY_NAME, ABBREVIATION, SEARCHABLE, TRANSLATABLE) VALUES (5, 'PRODUCT', 'defaultSku.description', 'desc', TRUE, TRUE);
INSERT INTO BLC_FIELD (FIELD_ID, ENTITY_TYPE, PROPERTY_NAME, ABBREVIATION, SEARCHABLE, TRANSLATABLE) VALUES (6, 'PRODUCT', 'defaultSku.longDescription', 'ldesc', TRUE, TRUE);
INSERT INTO BLC_FIELD (FIELD_ID, ENTITY_TYPE, PROPERTY_NAME, ABBREVIATION, SEARCHABLE, FACET_FIELD_TYPE) VALUES (7, 'PRODUCT', 'defaultCategory.name', 'categoryName', TRUE, 's');

INSERT INTO BLC_FIELD_SEARCH_TYPES (FIELD_ID, SEARCHABLE_FIELD_TYPE) VALUES (1, 't');
INSERT INTO BLC_FIELD_SEARCH_TYPES (FIELD_ID, SEARCHABLE_FIELD_TYPE) VALUES (2, 't');
INSERT INTO BLC_FIELD_SEARCH_TYPES (FIELD_ID, SEARCHABLE_FIELD_TYPE) VALUES (3, 't');
INSERT INTO BLC_FIELD_SEARCH_TYPES (FIELD_ID, SEARCHABLE_FIELD_TYPE) VALUES (4, 't');
INSERT INTO BLC_FIELD_SEARCH_TYPES (FIELD_ID, SEARCHABLE_FIELD_TYPE) VALUES (5, 't');
INSERT INTO BLC_FIELD_SEARCH_TYPES (FIELD_ID, SEARCHABLE_FIELD_TYPE) VALUES (6, 't');
INSERT INTO BLC_FIELD_SEARCH_TYPES (FIELD_ID, SEARCHABLE_FIELD_TYPE) VALUES (7, 't');

INSERT INTO BLC_SEARCH_FACET (SEARCH_FACET_ID, FIELD_ID, LABEL, SHOW_ON_SEARCH, MULTISELECT, SEARCH_DISPLAY_PRIORITY) VALUES (1, 1, 'Manufacturer', FALSE, TRUE, 1);
INSERT INTO BLC_SEARCH_FACET (SEARCH_FACET_ID, FIELD_ID, LABEL, SHOW_ON_SEARCH, MULTISELECT, SEARCH_DISPLAY_PRIORITY) VALUES (2, 2, 'Price', FALSE, TRUE, 1);
INSERT INTO BLC_SEARCH_FACET (SEARCH_FACET_ID, FIELD_ID, LABEL, SHOW_ON_SEARCH, MULTISELECT, SEARCH_DISPLAY_PRIORITY) VALUES (3, 7, 'categoryName', FALSE, TRUE, 1);

对于过滤,我可以使用 ?q=*&price=range[0:100] 对价格进行过滤。我想知道如何过滤制造商或类别名称?我在数据库中添加了与两者的价格相同的条目,但我无法按制造商或类别名称进行过滤。

为了排序, 我在 class 中找到了名为 "ProductSearchCriteria" 的 "sortQuery" 字段,但我不知道如何在查询字符串中使用排序。 我试过 ?q=*&sort=price+asc 并在 CatalogEndpoint.java 中设置 sortQuery,比如

searchCriteria.setSortQuery(sort);

然后调用方法,

result = getSearchService().findProductsByQuery(q, searchCriteria, sort);

但它不起作用。请帮忙。

我已经弄清楚如何在阔叶树中启用排序。

考虑 CatalagEndpoint.java 中的方法 findProductsByQuery()。像这样添加一个名为 sort 的查询参数,@QueryParam("sort") String sort。现在在 searchCriteria 中设置排序。

searchCriteria.setSortQuery(sort);

现在调用result = getSearchService().findProductsByQuery(q, searchCriteria);时,会执行SolrSearchServiceImpl.java的方法findProductsByQuery()。这将 return findProducts(query, facets, searchCriteria, null)。注意,这里 defaultSort 设置为空。 要启用排序,更改

result = getSearchService().findProductsByQuery(q, searchCriteria);

result = getSearchService().findProductsByQuery(q, searchCriteria, sort);

CatalogEndpoint.java。这会将排序查询字符串传递给 SolrSearchServiceImpl.java.

的方法 findProductsByQuery()

现在更改 SolrSearchServiceImpl.java 以将排序参数添加到方法 findProductsByQuery() 中。该方法将如下所示:

@Override
public ProductSearchResult findProductsByQuery(String query, ProductSearchCriteria searchCriteria, String sort) throws ServiceException {
    List<SearchFacetDTO> facets = getSearchFacets();
    query = "(" + sanitizeQuery(query) + ")";
    return findProducts(query, facets, searchCriteria, sort);
}

还必须在 SearchService 接口中添加排序,

public ProductSearchResult findProductsByQuery(String query, ProductSearchCriteria searchCriteria, String sort) throws ServiceException;

在方法 findProducts() 中添加排序参数,该方法将如下所示:

@Deprecated
protected ProductSearchResult findProducts(String qualifiedSolrQuery, List<SearchFacetDTO> facets, ProductSearchCriteria searchCriteria, String defaultSort) throws ServiceException {
    return findProducts(qualifiedSolrQuery, facets, searchCriteria, defaultSort, null);
}

更改后,排序查询字符串作为defaultSort发送,solr查询基于defaultSort生成。

现在在findProduct()方法中,调用了一个方法,

attachSortClause(solrQuery, searchCriteria, defaultSort);

该方法的实现如下:

protected void attachSortClause(SolrQuery query, ProductSearchCriteria searchCriteria, String defaultSort) {
    Map<String, String> solrFieldKeyMap = getSolrFieldKeyMap(searchCriteria);

    String sortQuery = searchCriteria.getSortQuery();
    if (StringUtils.isBlank(sortQuery)) {
            sortQuery = defaultSort;
    }

    if (StringUtils.isNotBlank(sortQuery)) {
            String[] sortFields = sortQuery.split(",");
            for (String sortField : sortFields) {
                String field = sortField.split(" ")[0];
                if (solrFieldKeyMap.containsKey(field)) {
                        field = solrFieldKeyMap.get(field);
                }
                ORDER order = "desc".equals(sortField.split(" ")[1]) ? ORDER.desc : ORDER.asc;

                if (field != null) {
                        query.addSortField(field, order);
                }
            }
    }
}

这是将 sortClauses 设置为 null,要设置 sortClauses,请将上面的实现更改为以下:

protected void attachSortClause(SolrQuery query, ProductSearchCriteria searchCriteria, String defaultSort) {
    Map<String, String> solrFieldKeyMap = getSolrFieldKeyMap(searchCriteria);

    String sortQuery = searchCriteria.getSortQuery();
    if (StringUtils.isBlank(sortQuery)) {
        sortQuery = defaultSort;
    }

    if (StringUtils.isNotBlank(sortQuery)) {
        String[] sortFields = sortQuery.split(",");
        for (String sortField : sortFields) {
            String field = sortField.split(" ")[0];
            if (solrFieldKeyMap.containsKey(field)) {
                field = solrFieldKeyMap.get(field);
            }
            ORDER order = "desc".equals(sortField.split(" ")[1]) ? ORDER.desc : ORDER.asc;

            if (field != null) {
                query.addSortField(field, order);
                List<SortClause> sortClauses = new ArrayList<SortClause>();
                SortClause clause = SortClause.create(field, order);
                sortClauses.add(clause);
                query.setSorts(sortClauses);
            }
        }
    }
}

这将根据查询字符串中传递的排序查询设置 sortClause。

现在当您通过 ?q=*&sort=price+asc 时,它将 return 您 json 的产品价格上涨。

如果您想查看 solr 如何创建索引和排序,请在站点 log4j.xml 的下面一行添加内容。

<logger name="org.broadleafcommerce.core.search.service"> <level value="trace" /> </logger>

当您的服务器启动时,solr 会创建所有索引,并且在 log4j.xml.

中放入上述行后,索引将显示为日志

当您请求 catalog/search/products?q=*&sort=price+asc 时,它会根据价格跟踪 productId。您可以在控制台中看到产品是按价格升序排列的。

[TRACE] 11:29:01 SolrSearchServiceImpl - SolrDocument{productId=10461}
[TRACE] 11:29:01 SolrSearchServiceImpl - SolrDocument{productId=10441}
[TRACE] 11:29:01 SolrSearchServiceImpl - SolrDocument{productId=10204}
[TRACE] 11:29:01 SolrSearchServiceImpl - SolrDocument{productId=10244}
[TRACE] 11:29:01 SolrSearchServiceImpl - SolrDocument{productId=10284}
[TRACE] 11:29:01 SolrSearchServiceImpl - SolrDocument{productId=10283}
[TRACE] 11:29:01 SolrSearchServiceImpl - SolrDocument{productId=10243}
[TRACE] 11:29:01 SolrSearchServiceImpl - SolrDocument{productId=10248}
[TRACE] 11:29:01 SolrSearchServiceImpl - SolrDocument{productId=10246}
[TRACE] 11:29:01 SolrSearchServiceImpl - SolrDocument{productId=10247}
[TRACE] 11:29:01 SolrSearchServiceImpl - SolrDocument{productId=10416}
[TRACE] 11:29:01 SolrSearchServiceImpl - SolrDocument{productId=10359}
[TRACE] 11:29:01 SolrSearchServiceImpl - SolrDocument{productId=10433}

并且在 JSON 中,您将根据上述跟踪的 productIds 的订单获得产品。

如果您仍然无法添加比这可能有所帮助的过滤器。

为了添加新的过滤器,您需要在数据库中输入一些条目,如下所示:

  1. 在 BLC_SEARCH_FACET table 中输入新字段(例如尺寸):
INSERT INTO BLC_SEARCH_FACET (SEARCH_FACET_ID, FIELD_ID, LABEL,  SHOW_ON_SEARCH, MULTISELECT, SEARCH_DISPLAY_PRIORITY) VALUES (5, 9, 'size', TRUE, TRUE, 1);
  1. 插入 table BLC_CAT_SEARCH_FACET_XREF 以将字段与类别相关联:
INSERT INTO BLC_CAT_SEARCH_FACET_XREF (CATEGORY_SEARCH_FACET_ID, CATEGORY_ID, SEARCH_FACET_ID, SEQUENCE) VALUES (10, 10050, 5, 9);
INSERT INTO BLC_CAT_SEARCH_FACET_XREF (CATEGORY_SEARCH_FACET_ID, CATEGORY_ID, SEARCH_FACET_ID, SEQUENCE) VALUES (11, 10054, 5, 9);
INSERT INTO BLC_CAT_SEARCH_FACET_XREF (CATEGORY_SEARCH_FACET_ID, CATEGORY_ID, SEARCH_FACET_ID, SEQUENCE) VALUES (12, 10055, 5, 9);
INSERT INTO BLC_CAT_SEARCH_FACET_XREF (CATEGORY_SEARCH_FACET_ID, CATEGORY_ID, SEARCH_FACET_ID, SEQUENCE) VALUES (13, 10056, 5, 9);
  1. 插入 table BLC_SEARCH_FACET_RANGE 以指定新字段的范围:
INSERT INTO BLC_SEARCH_FACET_RANGE (SEARCH_FACET_RANGE_ID, SEARCH_FACET_ID, MIN_VALUE, MAX_VALUE) VALUES (5, 5, 0, 5);
INSERT INTO BLC_SEARCH_FACET_RANGE (SEARCH_FACET_RANGE_ID, SEARCH_FACET_ID, MIN_VALUE, MAX_VALUE) VALUES (6, 5, 5, 10);
INSERT INTO BLC_SEARCH_FACET_RANGE (SEARCH_FACET_RANGE_ID, SEARCH_FACET_ID, MIN_VALUE, MAX_VALUE) VALUES (7, 5, 10, 15);
INSERT INTO BLC_SEARCH_FACET_RANGE (SEARCH_FACET_RANGE_ID, SEARCH_FACET_ID, MIN_VALUE, MAX_VALUE) VALUES (8, 5, 15, null);

完成此操作后,为了将此过滤器包含在产品中,您需要在定义新产品时在高级设置选项卡中指定产品属性 "size" 及其值。 就是这样,您现在将能够在左侧面板中看到尺寸过滤器。