我已使用以下详细信息设置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字段 相同的错误消息。
提前致谢
答案 0 :(得分:2)
在邮递员中,URL错误,尝试使用下面的一个点击
http://localhost:9200/productcatalog/_mapping/product
截至目前 _mapping缺失
您提供的网址https://www.elastic.co/guide/en/elasticsearch/reference/master/fielddata.html