mysql和Elasticsearch 一般同时使用。在对mysql增删改的同时,也需要在Elasticsearch同步数据操作。
首先,建立对应的java实体对象
public class HouseIndexTemplate {
private Long houseId;
private String title;
private int price;
private int area;
private Date createTime;
private Date lastUpdateTime;
private String cityEnName;
private String regionEnName;
private int direction;
private int distanceToSubway;
private String subwayLineName;
private String subwayStationName;
private String street;
private String district;
private String description;
private String layoutDesc;
private String traffic;
private String roundService;
private int rentWay;
private List<String> tags;
private List<HouseSuggest> suggest;
......
}
增加,修改都是先在es中查找有没有对应houseid,
没有的话是新建操作,找到一个的话修改操作,
找到多个的话是先删除后修改操作。原始的house信息都是从mysql里查到。
private void createOrUpdateIndex(HouseIndexMessage message) {
Long houseId = message.getHouseId();
House house = houseRepository.findOne(houseId);
if (house == null) {
logger.error("Index house {} dose not exist!", houseId);
this.index(houseId, message.getRetry() + 1);
return;
}
HouseIndexTemplate indexTemplate = new HouseIndexTemplate();
modelMapper.map(house, indexTemplate);
HouseDetail detail = houseDetailRepository.findByHouseId(houseId);
if (detail == null) {
// TODO 异常情况
}
modelMapper.map(detail, indexTemplate);
SupportAddress city = supportAddressRepository.findByEnNameAndLevel(house.getCityEnName(), SupportAddress.Level.CITY.getValue());
SupportAddress region = supportAddressRepository.findByEnNameAndLevel(house.getRegionEnName(), SupportAddress.Level.REGION.getValue());
String address = city.getCnName() + region.getCnName() + house.getStreet() + house.getDistrict() + detail.getDetailAddress();
ServiceResult<BaiduMapLocation> location = addressService.getBaiduMapLocation(city.getCnName(), address);
if (!location.isSuccess()) {
this.index(message.getHouseId(), message.getRetry() + 1);
return;
}
indexTemplate.setLocation(location.getResult());
List<HouseTag> tags = tagRepository.findAllByHouseId(houseId);
if (tags != null && !tags.isEmpty()) {
List<String> tagStrings = new ArrayList<>();
tags.forEach(houseTag -> tagStrings.add(houseTag.getName()));
indexTemplate.setTags(tagStrings);
}
SearchRequestBuilder requestBuilder = this.esClient.prepareSearch(INDEX_NAME).setTypes(INDEX_TYPE)
.setQuery(QueryBuilders.termQuery(HouseIndexKey.HOUSE_ID, houseId));
logger.debug(requestBuilder.toString());
SearchResponse searchResponse = requestBuilder.get();
boolean success;
long totalHit = searchResponse.getHits().getTotalHits();
if (totalHit == 0) {
success = create(indexTemplate);
} else if (totalHit == 1) {
String esId = searchResponse.getHits().getAt(0).getId();
success = update(esId, indexTemplate);
} else {
success = deleteAndCreate(totalHit, indexTemplate);
}
ServiceResult serviceResult = addressService.lbsUpload(location.getResult(), house.getStreet() + house.getDistrict(),
city.getCnName() + region.getCnName() + house.getStreet() + house.getDistrict(),
message.getHouseId(), house.getPrice(), house.getArea());
if (!success || !serviceResult.isSuccess()) {
this.index(message.getHouseId(), message.getRetry() + 1);
} else {
logger.debug("Index success with house " + houseId);
}
}
private void removeIndex(HouseIndexMessage message) {
Long houseId = message.getHouseId();
DeleteByQueryRequestBuilder builder = DeleteByQueryAction.INSTANCE
.newRequestBuilder(esClient)
.filter(QueryBuilders.termQuery(HouseIndexKey.HOUSE_ID, houseId))
.source(INDEX_NAME);
logger.debug("Delete by query for house: " + builder);
BulkByScrollResponse response = builder.get();
long deleted = response.getDeleted();
logger.debug("Delete total " + deleted);
ServiceResult serviceResult = addressService.removeLbs(houseId);
if (!serviceResult.isSuccess() || deleted <= 0) {
logger.warn("Did not remove data from es for response: " + response);
// 重新加入消息队列
this.remove(houseId, message.getRetry() + 1);
}
}
private boolean create(HouseIndexTemplate indexTemplate) {
if (!updateSuggest(indexTemplate)) {
return false;
}
try {
IndexResponse response = this.esClient.prepareIndex(INDEX_NAME, INDEX_TYPE)
.setSource(objectMapper.writeValueAsBytes(indexTemplate), XContentType.JSON).get();
logger.debug("Create index with house: " + indexTemplate.getHouseId());
if (response.status() == RestStatus.CREATED) {
return true;
} else {
return false;
}
} catch (JsonProcessingException e) {
logger.error("Error to index house " + indexTemplate.getHouseId(), e);
return false;
}
}
private boolean update(String esId, HouseIndexTemplate indexTemplate) {
if (!updateSuggest(indexTemplate)) {
return false;
}
try {
UpdateResponse response = this.esClient.prepareUpdate(INDEX_NAME, INDEX_TYPE, esId).setDoc(objectMapper.writeValueAsBytes(indexTemplate), XContentType.JSON).get();
logger.debug("Update index with house: " + indexTemplate.getHouseId());
if (response.status() == RestStatus.OK) {
return true;
} else {
return false;
}
} catch (JsonProcessingException e) {
logger.error("Error to index house " + indexTemplate.getHouseId(), e);
return false;
}
}
private boolean deleteAndCreate(long totalHit, HouseIndexTemplate indexTemplate) {
DeleteByQueryRequestBuilder builder = DeleteByQueryAction.INSTANCE
.newRequestBuilder(esClient)
.filter(QueryBuilders.termQuery(HouseIndexKey.HOUSE_ID, indexTemplate.getHouseId()))
.source(INDEX_NAME);
logger.debug("Delete by query for house: " + builder);
BulkByScrollResponse response = builder.get();
long deleted = response.getDeleted();
if (deleted != totalHit) {
logger.warn("Need delete {}, but {} was deleted!", totalHit, deleted);
return false;
} else {
return create(indexTemplate);
}
}