默认情况下,即使启用了字段数据,也会在文本字段上禁用字段数据

时间:2017-09-20 07:16:06

标签: java sorting elasticsearch spring-boot

我已使用以下详细信息设置ElasticSearch 5.6 索引 - 产品目录
类型 - 产品
我在ElasticSearch中有多个产品记录,下面是其中一个

                    "id": "xprod2148",
                    "name": "Acadia Wood Chair",
                    "type": null,
                    "description": "Craftsman meets classic in this attractive wood chair",
                    "items": [
                        {
                            "id": "xsku2148",
                            "type": "0",
                            "name": "Acadia Wood Chair",
                            "prices": [
                                {
                                    "type": "listPrices",
                                    "value": "179"
                                },
                                {
                                    "type": "plist3080002",
                                    "value": "121.49"
                                }
                            ],
                            "inventories": [
                                {
                                    "availabilityStatus": "In Stock",
                                    "url": "https://mesh.inventory.com/item?id=xsku2148"
                                }
                            ]
                        }
                    ],
                    "category": {
                        "id": "homeStoreSeatingDining",
                        "name": "Dining Chairs",
                        "href": null,
                        "parent": null
                    },
                    "images": [
                        {
                            "id": "m2966",
                            "name": "/crsdocroot/content/images/products/small/ST_AcadiaWoodChair_small.jpg",
                            "url": "Images/Product/crsdocroot/content/images/products/small/ST_AcadiaWoodChair_small.jpg"
                        },
                        {
                            "id": "m2968",
                            "name": "/crsdocroot/content/images/products/thumb/ST_AcadiaWoodChair_thumb.jpg",
                            "url": "Images/Product/crsdocroot/content/images/products/thumb/ST_AcadiaWoodChair_thumb.jpg"
                        },
                        {
                            "id": "m2969",
                            "name": "/crsdocroot/content/images/products/large/ST_AcadiaWoodChair_large.jpg",
                            "url": "Images/Product/crsdocroot/content/images/products/large/ST_AcadiaWoodChair_large.jpg"
                        }
                    ],
                    "brand": "Style by Zhanna"
                }
            }

除此之外,我正在使用 RestHighLevelClient 构建REST API来查询弹性搜索。
我想要实现的目标是什么?
构建REST api,按ID,名称,描述,品牌查询产品,并允许排序和过滤 到目前为止我做了什么?
我已经实现了基本搜索,现在想要根据id,name和brand等字段进行排序。

以下类负责从ElasticSearch获取数据并包含排序功能的代码(现在不能正常工作

package com.mesh.productlisting.dao.elasticsearch.impl;

import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Component;

import com.mesh.constants.CommonConstants;
import com.mesh.exception.DataAccessException;
import com.mesh.exception.util.ErrorResolver;
import com.mesh.productlisting.config.ElasticSearchRestClient;
import com.mesh.productlisting.config.condition.EnableElasticSearchCondition;
import com.mesh.productlisting.constants.SearchConstants;
import com.mesh.productlisting.dao.ProductDAO;

@Component
@Conditional(EnableElasticSearchCondition.class)
public class ElasticSearchProductDAOImpl implements ProductDAO {

    private final String className = ElasticSearchProductDAOImpl.class.getName();

    private final Logger logger = LoggerFactory.getLogger(ElasticSearchProductDAOImpl.class);

    @Value("${elasticsearch.productIndex}")
    private String productIndex;

    @Value("${elasticsearch.productIndexType}")
    private String productIndexType;

    @Value("${elasticsearch.product.searchfields}")
    private String searchProductByFields;

    @Autowired
    private ElasticSearchRestClient elasticSearchRestClient;

    @Autowired
    private ErrorResolver errorResolver;

    /**
     * This method returns the ElasticSearch response
     */
    @Override
    public String fetchProducts(String query, String rows, String filterQuery, String sortByField, String sortOrder,
            String start, String priceStart, String priceEnd) {

        final String methodName = "fetchProducts";
        logger.info("Entering " + className + " " + methodName);
        String jsonResponse = null;

        jsonResponse = queryElasticSearch(query, rows, filterQuery, sortByField, sortOrder, start, priceStart,
                priceEnd);

        logger.info("Exiting " + className + " " + methodName);
        return jsonResponse;
    }

    /**
     * This method query the ElasticSearch and gets the response
     * 
     * @param query
     * @param rows
     * @param filterQuery
     * @param sortByField
     * @param sortOrder
     * @param start
     * @param priceStart
     * @param priceEnd
     * @return String
     */
    private String queryElasticSearch(String query, String rows, String filterQuery, String sortByField,
            String sortOrder, String start, String priceStart, String priceEnd) {

        RestHighLevelClient restHighLevelClient = elasticSearchRestClient.getHighLevelRestClient();

        SearchRequest searchRequest = new SearchRequest(productIndex);
        searchRequest.types(productIndexType);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        if (start != null) {
            searchSourceBuilder.from(Integer.parseInt(start));
        }
        if (rows != null) {
            searchSourceBuilder.size(Integer.parseInt(rows));
        }

        String searchProductByFieldsArray[] = searchProductByFields.split(",");

        searchSourceBuilder.query(QueryBuilders.multiMatchQuery(query, searchProductByFieldsArray));

        searchSourceBuilder.sort(new FieldSortBuilder("brand").order(SortOrder.DESC));

        //searchSourceBuilder.fetchSource(false);

        searchRequest.source(searchSourceBuilder);

        Header headers = new BasicHeader("Content-Type", "application/json");

        SearchResponse searchResponse = null;

        try {

            searchResponse = restHighLevelClient.search(searchRequest, headers);

        } catch (Exception e) {

            e.printStackTrace();

            logger.error("exception caught while querying ElasticSearch " + e.getMessage());

            throw new DataAccessException(CommonConstants.SERVICE_NOT_AVAILABLE, errorResolver
                    .getErrorMessage(SearchConstants.ElASTIC_SEARCH_UNAVAILABLE, CommonConstants.EMPTY_STRING));

        }

        if (searchResponse == null)
            throw new DataAccessException(CommonConstants.BAD_REQUEST,
                    errorResolver.getErrorMessage(SearchConstants.NO_PRODUCT_FOUND, CommonConstants.EMPTY_STRING));
        else {

            return searchResponse.toString();
        }
    }

}


目前我正在尝试对品牌进行排序,我将获得例外情况

{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"Fielddata is disabled on text fields by default. Set fielddata=true on [brand] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"productcatalog","node":"L_QzCcz-Q6-T5Up3Om248A","reason":{"type":"illegal_argument_exception","reason":"Fielddata is disabled on text fields by default. Set fielddata=true on [brand] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."}}]},"status":400}

要纠正此问题,我已按照此 https://www.elastic.co/guide/en/elasticsearch/reference/master/fielddata.html

并在POSTMAN中尝试(附快照)

check image link for postman request and response


即使遵循ElasticSearch文档,我也无法解决此问题并继续获得与_uid字段 相同的错误消息。

提前致谢

1 个答案:

答案 0 :(得分:2)

在邮递员中,URL错误,尝试使用下面的一个点击 http://localhost:9200/productcatalog/_mapping/product
截至目前 _mapping缺失 您提供的网址https://www.elastic.co/guide/en/elasticsearch/reference/master/fielddata.html

中提到了相同的内容

您应该得到如下Response

之类的回复