mirror of
https://github.com/chatopera/cosin.git
synced 2025-08-01 16:38:02 +08:00
Fix HighlightBuilder's package path
This commit is contained in:
parent
72545a9db7
commit
7bfe151a0e
@ -21,7 +21,7 @@ import com.chatopera.cc.model.Topic;
|
|||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.elasticsearch.index.query.Operator;
|
import org.elasticsearch.index.query.Operator;
|
||||||
import org.elasticsearch.index.query.QueryStringQueryBuilder;
|
import org.elasticsearch.index.query.QueryStringQueryBuilder;
|
||||||
import org.elasticsearch.search.highlight.HighlightBuilder;
|
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
||||||
import org.elasticsearch.search.sort.FieldSortBuilder;
|
import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||||
import org.elasticsearch.search.sort.SortOrder;
|
import org.elasticsearch.search.sort.SortOrder;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -19,7 +19,7 @@ package com.chatopera.cc.persistence.es;
|
|||||||
import com.chatopera.cc.model.KbsTopic;
|
import com.chatopera.cc.model.KbsTopic;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.elasticsearch.index.query.*;
|
import org.elasticsearch.index.query.*;
|
||||||
import org.elasticsearch.search.highlight.HighlightBuilder;
|
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
||||||
import org.elasticsearch.search.sort.FieldSortBuilder;
|
import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||||
import org.elasticsearch.search.sort.SortOrder;
|
import org.elasticsearch.search.sort.SortOrder;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -20,7 +20,7 @@ import com.chatopera.cc.basic.MainContext;
|
|||||||
import com.chatopera.cc.model.QuickReply;
|
import com.chatopera.cc.model.QuickReply;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.elasticsearch.index.query.*;
|
import org.elasticsearch.index.query.*;
|
||||||
import org.elasticsearch.search.highlight.HighlightBuilder;
|
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
||||||
import org.elasticsearch.search.sort.FieldSortBuilder;
|
import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||||
import org.elasticsearch.search.sort.SortOrder;
|
import org.elasticsearch.search.sort.SortOrder;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -20,7 +20,7 @@ import com.chatopera.cc.model.Topic;
|
|||||||
import com.chatopera.cc.persistence.repository.XiaoEUKResultMapper;
|
import com.chatopera.cc.persistence.repository.XiaoEUKResultMapper;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.elasticsearch.index.query.*;
|
import org.elasticsearch.index.query.*;
|
||||||
import org.elasticsearch.search.highlight.HighlightBuilder;
|
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
||||||
import org.elasticsearch.search.sort.FieldSortBuilder;
|
import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||||
import org.elasticsearch.search.sort.SortOrder;
|
import org.elasticsearch.search.sort.SortOrder;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -1,208 +1,208 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2017 优客服-多渠道客服系统
|
* Copyright (C) 2017 优客服-多渠道客服系统
|
||||||
* Modifications copyright (C) 2018-2019 Chatopera Inc, <https://www.chatopera.com>
|
* Modifications copyright (C) 2018-2019 Chatopera Inc, <https://www.chatopera.com>
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.chatopera.cc.persistence.es;
|
package com.chatopera.cc.persistence.es;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonEncoding;
|
import com.fasterxml.jackson.core.JsonEncoding;
|
||||||
import com.fasterxml.jackson.core.JsonFactory;
|
import com.fasterxml.jackson.core.JsonFactory;
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
import org.apache.commons.beanutils.PropertyUtils;
|
import org.apache.commons.beanutils.PropertyUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.elasticsearch.action.get.GetResponse;
|
import org.elasticsearch.action.get.GetResponse;
|
||||||
import org.elasticsearch.action.get.MultiGetItemResponse;
|
import org.elasticsearch.action.get.MultiGetItemResponse;
|
||||||
import org.elasticsearch.action.get.MultiGetResponse;
|
import org.elasticsearch.action.get.MultiGetResponse;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
import org.elasticsearch.search.SearchHitField;
|
import org.elasticsearch.search.SearchHitField;
|
||||||
import org.elasticsearch.search.highlight.HighlightField;
|
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.elasticsearch.ElasticsearchException;
|
import org.springframework.data.elasticsearch.ElasticsearchException;
|
||||||
import org.springframework.data.elasticsearch.annotations.Document;
|
import org.springframework.data.elasticsearch.annotations.Document;
|
||||||
import org.springframework.data.elasticsearch.annotations.ScriptedField;
|
import org.springframework.data.elasticsearch.annotations.ScriptedField;
|
||||||
import org.springframework.data.elasticsearch.core.AbstractResultMapper;
|
import org.springframework.data.elasticsearch.core.AbstractResultMapper;
|
||||||
import org.springframework.data.elasticsearch.core.DefaultEntityMapper;
|
import org.springframework.data.elasticsearch.core.DefaultEntityMapper;
|
||||||
import org.springframework.data.elasticsearch.core.EntityMapper;
|
import org.springframework.data.elasticsearch.core.EntityMapper;
|
||||||
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
|
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
|
||||||
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
|
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
||||||
import org.springframework.data.mapping.PersistentProperty;
|
import org.springframework.data.mapping.PersistentProperty;
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class UKResultMapper extends AbstractResultMapper {
|
public class UKResultMapper extends AbstractResultMapper {
|
||||||
|
|
||||||
private MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
|
private MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
|
||||||
|
|
||||||
public UKResultMapper() {
|
public UKResultMapper() {
|
||||||
super(new DefaultEntityMapper());
|
super(new DefaultEntityMapper());
|
||||||
}
|
}
|
||||||
|
|
||||||
public UKResultMapper(MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext) {
|
public UKResultMapper(MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext) {
|
||||||
super(new DefaultEntityMapper());
|
super(new DefaultEntityMapper());
|
||||||
this.mappingContext = mappingContext;
|
this.mappingContext = mappingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UKResultMapper(EntityMapper entityMapper) {
|
public UKResultMapper(EntityMapper entityMapper) {
|
||||||
super(entityMapper);
|
super(entityMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UKResultMapper(
|
public UKResultMapper(
|
||||||
MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext,
|
MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext,
|
||||||
EntityMapper entityMapper) {
|
EntityMapper entityMapper) {
|
||||||
super(entityMapper);
|
super(entityMapper);
|
||||||
this.mappingContext = mappingContext;
|
this.mappingContext = mappingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
|
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
|
||||||
long totalHits = response.getHits().totalHits();
|
long totalHits = response.getHits().totalHits();
|
||||||
List<T> results = new ArrayList<T>();
|
List<T> results = new ArrayList<T>();
|
||||||
for (SearchHit hit : response.getHits()) {
|
for (SearchHit hit : response.getHits()) {
|
||||||
if (hit != null) {
|
if (hit != null) {
|
||||||
T result = null;
|
T result = null;
|
||||||
if (StringUtils.isNotBlank(hit.sourceAsString())) {
|
if (StringUtils.isNotBlank(hit.sourceAsString())) {
|
||||||
result = mapEntity(hit.sourceAsString() , hit , clazz);
|
result = mapEntity(hit.sourceAsString() , hit , clazz);
|
||||||
} else {
|
} else {
|
||||||
result = mapEntity(hit.getFields().values() , hit , clazz);
|
result = mapEntity(hit.getFields().values() , hit , clazz);
|
||||||
}
|
}
|
||||||
setPersistentEntityId(result, hit.getId(), clazz);
|
setPersistentEntityId(result, hit.getId(), clazz);
|
||||||
populateScriptFields(result, hit);
|
populateScriptFields(result, hit);
|
||||||
results.add(result);
|
results.add(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AggregatedPageImpl<T>(results, pageable, totalHits);
|
return new AggregatedPageImpl<T>(results, pageable, totalHits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T mapEntity(String source , SearchHit hit , Class<T> clazz) {
|
public <T> T mapEntity(String source , SearchHit hit , Class<T> clazz) {
|
||||||
T t = mapEntity(source , clazz) ;
|
T t = mapEntity(source , clazz) ;
|
||||||
|
|
||||||
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
|
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
|
||||||
HighlightField highlightNameField = highlightFields.get("title");
|
HighlightField highlightNameField = highlightFields.get("title");
|
||||||
HighlightField contentHightlightField = highlightFields.get("content");
|
HighlightField contentHightlightField = highlightFields.get("content");
|
||||||
try {
|
try {
|
||||||
if(highlightNameField!=null&&highlightNameField.fragments()!=null){
|
if(highlightNameField!=null&&highlightNameField.fragments()!=null){
|
||||||
PropertyUtils.setProperty(t, "title" , highlightNameField.fragments()[0].string());
|
PropertyUtils.setProperty(t, "title" , highlightNameField.fragments()[0].string());
|
||||||
}
|
}
|
||||||
if(contentHightlightField!=null){
|
if(contentHightlightField!=null){
|
||||||
PropertyUtils.setProperty(t, "content" , contentHightlightField.fragments()[0].string());
|
PropertyUtils.setProperty(t, "content" , contentHightlightField.fragments()[0].string());
|
||||||
}
|
}
|
||||||
PropertyUtils.setProperty(t, "id" , hit.getId());
|
PropertyUtils.setProperty(t, "id" , hit.getId());
|
||||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> void populateScriptFields(T result, SearchHit hit) {
|
private <T> void populateScriptFields(T result, SearchHit hit) {
|
||||||
if (hit.getFields() != null && !hit.getFields().isEmpty() && result != null) {
|
if (hit.getFields() != null && !hit.getFields().isEmpty() && result != null) {
|
||||||
for (java.lang.reflect.Field field : result.getClass().getDeclaredFields()) {
|
for (java.lang.reflect.Field field : result.getClass().getDeclaredFields()) {
|
||||||
ScriptedField scriptedField = field.getAnnotation(ScriptedField.class);
|
ScriptedField scriptedField = field.getAnnotation(ScriptedField.class);
|
||||||
if (scriptedField != null) {
|
if (scriptedField != null) {
|
||||||
String name = scriptedField.name().isEmpty() ? field.getName() : scriptedField.name();
|
String name = scriptedField.name().isEmpty() ? field.getName() : scriptedField.name();
|
||||||
SearchHitField searchHitField = hit.getFields().get(name);
|
SearchHitField searchHitField = hit.getFields().get(name);
|
||||||
if (searchHitField != null) {
|
if (searchHitField != null) {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
try {
|
try {
|
||||||
if(name.equals("title") && hit.getHighlightFields().get("title")!=null){
|
if(name.equals("title") && hit.getHighlightFields().get("title")!=null){
|
||||||
field.set(result, hit.getHighlightFields().get("title").fragments()[0].string());
|
field.set(result, hit.getHighlightFields().get("title").fragments()[0].string());
|
||||||
}else{
|
}else{
|
||||||
field.set(result, searchHitField.getValue());
|
field.set(result, searchHitField.getValue());
|
||||||
}
|
}
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new ElasticsearchException("failed to set scripted field: " + name + " with value: "
|
throw new ElasticsearchException("failed to set scripted field: " + name + " with value: "
|
||||||
+ searchHitField.getValue(), e);
|
+ searchHitField.getValue(), e);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new ElasticsearchException("failed to access scripted field: " + name, e);
|
throw new ElasticsearchException("failed to access scripted field: " + name, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public <T> T mapEntity(Collection<SearchHitField> values, SearchHit hit , Class<T> clazz) {
|
public <T> T mapEntity(Collection<SearchHitField> values, SearchHit hit , Class<T> clazz) {
|
||||||
return mapEntity(buildJSONFromFields(values) , hit , clazz);
|
return mapEntity(buildJSONFromFields(values) , hit , clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildJSONFromFields(Collection<SearchHitField> values) {
|
private String buildJSONFromFields(Collection<SearchHitField> values) {
|
||||||
JsonFactory nodeFactory = new JsonFactory();
|
JsonFactory nodeFactory = new JsonFactory();
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
JsonGenerator generator = nodeFactory.createGenerator(stream, JsonEncoding.UTF8);
|
JsonGenerator generator = nodeFactory.createGenerator(stream, JsonEncoding.UTF8);
|
||||||
generator.writeStartObject();
|
generator.writeStartObject();
|
||||||
for (SearchHitField value : values) {
|
for (SearchHitField value : values) {
|
||||||
if (value.getValues().size() > 1) {
|
if (value.getValues().size() > 1) {
|
||||||
generator.writeArrayFieldStart(value.getName());
|
generator.writeArrayFieldStart(value.getName());
|
||||||
for (Object val : value.getValues()) {
|
for (Object val : value.getValues()) {
|
||||||
generator.writeObject(val);
|
generator.writeObject(val);
|
||||||
}
|
}
|
||||||
generator.writeEndArray();
|
generator.writeEndArray();
|
||||||
} else {
|
} else {
|
||||||
generator.writeObjectField(value.getName(), value.getValue());
|
generator.writeObjectField(value.getName(), value.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
generator.writeEndObject();
|
generator.writeEndObject();
|
||||||
generator.flush();
|
generator.flush();
|
||||||
return new String(stream.toByteArray(), Charset.forName("UTF-8"));
|
return new String(stream.toByteArray(), StandardCharsets.UTF_8);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T mapResult(GetResponse response, Class<T> clazz) {
|
public <T> T mapResult(GetResponse response, Class<T> clazz) {
|
||||||
T result = mapEntity(response.getSourceAsString(), clazz);
|
T result = mapEntity(response.getSourceAsString(), clazz);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
setPersistentEntityId(result, response.getId(), clazz);
|
setPersistentEntityId(result, response.getId(), clazz);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> LinkedList<T> mapResults(MultiGetResponse responses, Class<T> clazz) {
|
public <T> LinkedList<T> mapResults(MultiGetResponse responses, Class<T> clazz) {
|
||||||
LinkedList<T> list = new LinkedList<T>();
|
LinkedList<T> list = new LinkedList<T>();
|
||||||
for (MultiGetItemResponse response : responses.getResponses()) {
|
for (MultiGetItemResponse response : responses.getResponses()) {
|
||||||
if (!response.isFailed() && response.getResponse().isExists()) {
|
if (!response.isFailed() && response.getResponse().isExists()) {
|
||||||
T result = mapEntity(response.getResponse().getSourceAsString(), clazz);
|
T result = mapEntity(response.getResponse().getSourceAsString(), clazz);
|
||||||
setPersistentEntityId(result, response.getResponse().getId(), clazz);
|
setPersistentEntityId(result, response.getResponse().getId(), clazz);
|
||||||
list.add(result);
|
list.add(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> void setPersistentEntityId(T result, String id, Class<T> clazz) {
|
private <T> void setPersistentEntityId(T result, String id, Class<T> clazz) {
|
||||||
|
|
||||||
if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) {
|
if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) {
|
||||||
|
|
||||||
ElasticsearchPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(clazz);
|
ElasticsearchPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(clazz);
|
||||||
PersistentProperty<?> idProperty = persistentEntity.getIdProperty();
|
PersistentProperty<?> idProperty = persistentEntity.getIdProperty();
|
||||||
|
|
||||||
// Only deal with String because ES generated Ids are strings !
|
// Only deal with String because ES generated Ids are strings !
|
||||||
if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) {
|
if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) {
|
||||||
persistentEntity.getPropertyAccessor(result).setProperty(idProperty, id);
|
persistentEntity.getPropertyAccessor(result).setProperty(idProperty, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,208 +1,208 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2017 优客服-多渠道客服系统
|
* Copyright (C) 2017 优客服-多渠道客服系统
|
||||||
* Modifications copyright (C) 2018-2019 Chatopera Inc, <https://www.chatopera.com>
|
* Modifications copyright (C) 2018-2019 Chatopera Inc, <https://www.chatopera.com>
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.chatopera.cc.persistence.repository;
|
package com.chatopera.cc.persistence.repository;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonEncoding;
|
import com.fasterxml.jackson.core.JsonEncoding;
|
||||||
import com.fasterxml.jackson.core.JsonFactory;
|
import com.fasterxml.jackson.core.JsonFactory;
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
import org.apache.commons.beanutils.PropertyUtils;
|
import org.apache.commons.beanutils.PropertyUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.elasticsearch.action.get.GetResponse;
|
import org.elasticsearch.action.get.GetResponse;
|
||||||
import org.elasticsearch.action.get.MultiGetItemResponse;
|
import org.elasticsearch.action.get.MultiGetItemResponse;
|
||||||
import org.elasticsearch.action.get.MultiGetResponse;
|
import org.elasticsearch.action.get.MultiGetResponse;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
import org.elasticsearch.search.SearchHitField;
|
import org.elasticsearch.search.SearchHitField;
|
||||||
import org.elasticsearch.search.highlight.HighlightField;
|
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.elasticsearch.ElasticsearchException;
|
import org.springframework.data.elasticsearch.ElasticsearchException;
|
||||||
import org.springframework.data.elasticsearch.annotations.Document;
|
import org.springframework.data.elasticsearch.annotations.Document;
|
||||||
import org.springframework.data.elasticsearch.annotations.ScriptedField;
|
import org.springframework.data.elasticsearch.annotations.ScriptedField;
|
||||||
import org.springframework.data.elasticsearch.core.AbstractResultMapper;
|
import org.springframework.data.elasticsearch.core.AbstractResultMapper;
|
||||||
import org.springframework.data.elasticsearch.core.DefaultEntityMapper;
|
import org.springframework.data.elasticsearch.core.DefaultEntityMapper;
|
||||||
import org.springframework.data.elasticsearch.core.EntityMapper;
|
import org.springframework.data.elasticsearch.core.EntityMapper;
|
||||||
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
|
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
|
||||||
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
|
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
||||||
import org.springframework.data.mapping.PersistentProperty;
|
import org.springframework.data.mapping.PersistentProperty;
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class XiaoEUKResultMapper extends AbstractResultMapper {
|
public class XiaoEUKResultMapper extends AbstractResultMapper {
|
||||||
|
|
||||||
private MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
|
private MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
|
||||||
|
|
||||||
public XiaoEUKResultMapper() {
|
public XiaoEUKResultMapper() {
|
||||||
super(new DefaultEntityMapper());
|
super(new DefaultEntityMapper());
|
||||||
}
|
}
|
||||||
|
|
||||||
public XiaoEUKResultMapper(MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext) {
|
public XiaoEUKResultMapper(MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext) {
|
||||||
super(new DefaultEntityMapper());
|
super(new DefaultEntityMapper());
|
||||||
this.mappingContext = mappingContext;
|
this.mappingContext = mappingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public XiaoEUKResultMapper(EntityMapper entityMapper) {
|
public XiaoEUKResultMapper(EntityMapper entityMapper) {
|
||||||
super(entityMapper);
|
super(entityMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public XiaoEUKResultMapper(
|
public XiaoEUKResultMapper(
|
||||||
MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext,
|
MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext,
|
||||||
EntityMapper entityMapper) {
|
EntityMapper entityMapper) {
|
||||||
super(entityMapper);
|
super(entityMapper);
|
||||||
this.mappingContext = mappingContext;
|
this.mappingContext = mappingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
|
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
|
||||||
long totalHits = response.getHits().totalHits();
|
long totalHits = response.getHits().totalHits();
|
||||||
List<T> results = new ArrayList<T>();
|
List<T> results = new ArrayList<T>();
|
||||||
for (SearchHit hit : response.getHits()) {
|
for (SearchHit hit : response.getHits()) {
|
||||||
if (hit != null) {
|
if (hit != null) {
|
||||||
T result = null;
|
T result = null;
|
||||||
if (StringUtils.isNotBlank(hit.sourceAsString())) {
|
if (StringUtils.isNotBlank(hit.sourceAsString())) {
|
||||||
result = mapEntity(hit.sourceAsString() , hit , clazz);
|
result = mapEntity(hit.sourceAsString() , hit , clazz);
|
||||||
} else {
|
} else {
|
||||||
result = mapEntity(hit.getFields().values() , hit , clazz);
|
result = mapEntity(hit.getFields().values() , hit , clazz);
|
||||||
}
|
}
|
||||||
setPersistentEntityId(result, hit.getId(), clazz);
|
setPersistentEntityId(result, hit.getId(), clazz);
|
||||||
populateScriptFields(result, hit);
|
populateScriptFields(result, hit);
|
||||||
results.add(result);
|
results.add(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AggregatedPageImpl<T>(results, pageable, totalHits);
|
return new AggregatedPageImpl<T>(results, pageable, totalHits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T mapEntity(String source , SearchHit hit , Class<T> clazz) {
|
public <T> T mapEntity(String source , SearchHit hit , Class<T> clazz) {
|
||||||
T t = mapEntity(source , clazz) ;
|
T t = mapEntity(source , clazz) ;
|
||||||
|
|
||||||
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
|
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
|
||||||
HighlightField highlightNameField = highlightFields.get("title");
|
HighlightField highlightNameField = highlightFields.get("title");
|
||||||
HighlightField contentHightlightField = highlightFields.get("content");
|
HighlightField contentHightlightField = highlightFields.get("content");
|
||||||
try {
|
try {
|
||||||
if(highlightNameField!=null&&highlightNameField.fragments()!=null){
|
if(highlightNameField!=null&&highlightNameField.fragments()!=null){
|
||||||
PropertyUtils.setProperty(t, "title" , highlightNameField.fragments()[0].string());
|
PropertyUtils.setProperty(t, "title" , highlightNameField.fragments()[0].string());
|
||||||
}
|
}
|
||||||
if(contentHightlightField!=null){
|
if(contentHightlightField!=null){
|
||||||
PropertyUtils.setProperty(t, "content" , contentHightlightField.fragments()[0].string());
|
PropertyUtils.setProperty(t, "content" , contentHightlightField.fragments()[0].string());
|
||||||
}
|
}
|
||||||
PropertyUtils.setProperty(t, "id" , hit.getId());
|
PropertyUtils.setProperty(t, "id" , hit.getId());
|
||||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> void populateScriptFields(T result, SearchHit hit) {
|
private <T> void populateScriptFields(T result, SearchHit hit) {
|
||||||
if (hit.getFields() != null && !hit.getFields().isEmpty() && result != null) {
|
if (hit.getFields() != null && !hit.getFields().isEmpty() && result != null) {
|
||||||
for (java.lang.reflect.Field field : result.getClass().getDeclaredFields()) {
|
for (java.lang.reflect.Field field : result.getClass().getDeclaredFields()) {
|
||||||
ScriptedField scriptedField = field.getAnnotation(ScriptedField.class);
|
ScriptedField scriptedField = field.getAnnotation(ScriptedField.class);
|
||||||
if (scriptedField != null) {
|
if (scriptedField != null) {
|
||||||
String name = scriptedField.name().isEmpty() ? field.getName() : scriptedField.name();
|
String name = scriptedField.name().isEmpty() ? field.getName() : scriptedField.name();
|
||||||
SearchHitField searchHitField = hit.getFields().get(name);
|
SearchHitField searchHitField = hit.getFields().get(name);
|
||||||
if (searchHitField != null) {
|
if (searchHitField != null) {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
try {
|
try {
|
||||||
if(name.equals("title") && hit.getHighlightFields().get("title")!=null){
|
if(name.equals("title") && hit.getHighlightFields().get("title")!=null){
|
||||||
field.set(result, hit.getHighlightFields().get("title").fragments()[0].string());
|
field.set(result, hit.getHighlightFields().get("title").fragments()[0].string());
|
||||||
}else{
|
}else{
|
||||||
field.set(result, searchHitField.getValue());
|
field.set(result, searchHitField.getValue());
|
||||||
}
|
}
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new ElasticsearchException("failed to set scripted field: " + name + " with value: "
|
throw new ElasticsearchException("failed to set scripted field: " + name + " with value: "
|
||||||
+ searchHitField.getValue(), e);
|
+ searchHitField.getValue(), e);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new ElasticsearchException("failed to access scripted field: " + name, e);
|
throw new ElasticsearchException("failed to access scripted field: " + name, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public <T> T mapEntity(Collection<SearchHitField> values, SearchHit hit , Class<T> clazz) {
|
public <T> T mapEntity(Collection<SearchHitField> values, SearchHit hit , Class<T> clazz) {
|
||||||
return mapEntity(buildJSONFromFields(values) , hit , clazz);
|
return mapEntity(buildJSONFromFields(values) , hit , clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildJSONFromFields(Collection<SearchHitField> values) {
|
private String buildJSONFromFields(Collection<SearchHitField> values) {
|
||||||
JsonFactory nodeFactory = new JsonFactory();
|
JsonFactory nodeFactory = new JsonFactory();
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
JsonGenerator generator = nodeFactory.createGenerator(stream, JsonEncoding.UTF8);
|
JsonGenerator generator = nodeFactory.createGenerator(stream, JsonEncoding.UTF8);
|
||||||
generator.writeStartObject();
|
generator.writeStartObject();
|
||||||
for (SearchHitField value : values) {
|
for (SearchHitField value : values) {
|
||||||
if (value.getValues().size() > 1) {
|
if (value.getValues().size() > 1) {
|
||||||
generator.writeArrayFieldStart(value.getName());
|
generator.writeArrayFieldStart(value.getName());
|
||||||
for (Object val : value.getValues()) {
|
for (Object val : value.getValues()) {
|
||||||
generator.writeObject(val);
|
generator.writeObject(val);
|
||||||
}
|
}
|
||||||
generator.writeEndArray();
|
generator.writeEndArray();
|
||||||
} else {
|
} else {
|
||||||
generator.writeObjectField(value.getName(), value.getValue());
|
generator.writeObjectField(value.getName(), value.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
generator.writeEndObject();
|
generator.writeEndObject();
|
||||||
generator.flush();
|
generator.flush();
|
||||||
return new String(stream.toByteArray(), Charset.forName("UTF-8"));
|
return new String(stream.toByteArray(), StandardCharsets.UTF_8);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T mapResult(GetResponse response, Class<T> clazz) {
|
public <T> T mapResult(GetResponse response, Class<T> clazz) {
|
||||||
T result = mapEntity(response.getSourceAsString(), clazz);
|
T result = mapEntity(response.getSourceAsString(), clazz);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
setPersistentEntityId(result, response.getId(), clazz);
|
setPersistentEntityId(result, response.getId(), clazz);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> LinkedList<T> mapResults(MultiGetResponse responses, Class<T> clazz) {
|
public <T> LinkedList<T> mapResults(MultiGetResponse responses, Class<T> clazz) {
|
||||||
LinkedList<T> list = new LinkedList<T>();
|
LinkedList<T> list = new LinkedList<T>();
|
||||||
for (MultiGetItemResponse response : responses.getResponses()) {
|
for (MultiGetItemResponse response : responses.getResponses()) {
|
||||||
if (!response.isFailed() && response.getResponse().isExists()) {
|
if (!response.isFailed() && response.getResponse().isExists()) {
|
||||||
T result = mapEntity(response.getResponse().getSourceAsString(), clazz);
|
T result = mapEntity(response.getResponse().getSourceAsString(), clazz);
|
||||||
setPersistentEntityId(result, response.getResponse().getId(), clazz);
|
setPersistentEntityId(result, response.getResponse().getId(), clazz);
|
||||||
list.add(result);
|
list.add(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> void setPersistentEntityId(T result, String id, Class<T> clazz) {
|
private <T> void setPersistentEntityId(T result, String id, Class<T> clazz) {
|
||||||
|
|
||||||
if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) {
|
if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) {
|
||||||
|
|
||||||
ElasticsearchPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(clazz);
|
ElasticsearchPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(clazz);
|
||||||
PersistentProperty<?> idProperty = persistentEntity.getIdProperty();
|
PersistentProperty<?> idProperty = persistentEntity.getIdProperty();
|
||||||
|
|
||||||
// Only deal with String because ES generated Ids are strings !
|
// Only deal with String because ES generated Ids are strings !
|
||||||
if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) {
|
if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) {
|
||||||
persistentEntity.getPropertyAccessor(result).setProperty(idProperty, id);
|
persistentEntity.getPropertyAccessor(result).setProperty(idProperty, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user