Feat: [后台]:完成关键字搜索书签功能

This commit is contained in:
fanxb 2019-07-25 19:37:26 +08:00
parent 1244c33785
commit 89bb03e5aa
8 changed files with 141 additions and 34 deletions

View File

@ -1,6 +1,7 @@
package com.fanxb.bookmark.business.bookmark.controller;
import com.fanxb.bookmark.business.bookmark.entity.BatchDeleteBody;
import com.fanxb.bookmark.business.bookmark.entity.BookmarkEs;
import com.fanxb.bookmark.business.bookmark.entity.MoveNodeBody;
import com.fanxb.bookmark.business.bookmark.service.BookmarkService;
import com.fanxb.bookmark.common.entity.Bookmark;
@ -10,6 +11,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* 类功能简述
* 类功能详述
@ -109,4 +112,10 @@ public class BookmarkController {
return Result.success(null);
}
@GetMapping("/searchUserBookmark")
public Result searchUserBookmark(String content) {
List<BookmarkEs> res = bookmarkService.searchUserBookmark(UserContextHolder.get().getUserId(), content);
return Result.success(res);
}
}

View File

@ -133,5 +133,15 @@ public interface BookmarkDao {
*/
void updatePathAndSort(@Param("userId") int userId, @Param("bookmarkId") int bookmarkId, @Param("path") String path, @Param("sort") int sort);
/**
* Description: 获取某个文件夹下所有的节点id
*
* @param userId userId
* @param folderId folderId
* @return java.util.List<java.lang.Integer>
* @author fanxb
* @date 2019/7/25 14:14
*/
List<Integer> getChildrenBookmarkId(@Param("userId") int userId, @Param("folderId") int folderId);
}

View File

@ -1,7 +1,6 @@
package com.fanxb.bookmark.business.bookmark.entity;
import com.fanxb.bookmark.common.entity.Bookmark;
import com.fanxb.bookmark.common.entity.EsInsertEntity;
import lombok.Data;
/**
@ -12,20 +11,17 @@ import lombok.Data;
* @date 2019/7/24 15:07
*/
@Data
public class BookmarkEs extends EsInsertEntity<BookmarkEs> {
private Integer bookmarkId;
public class BookmarkEs {
private Integer userId;
private Integer bookmarkId;
private String name;
private String url;
public BookmarkEs() {
super();
}
public BookmarkEs(Bookmark bookmark) {
super();
this.setData(this);
this.bookmarkId = bookmark.getBookmarkId();
this.setBookmarkId(bookmark.getBookmarkId());
this.userId = bookmark.getUserId();
this.name = bookmark.getName();
this.url = bookmark.getUrl();

View File

@ -5,9 +5,13 @@ import com.fanxb.bookmark.business.bookmark.entity.BookmarkEs;
import com.fanxb.bookmark.business.bookmark.entity.MoveNodeBody;
import com.fanxb.bookmark.common.constant.EsConstant;
import com.fanxb.bookmark.common.entity.Bookmark;
import com.fanxb.bookmark.common.entity.EsEntity;
import com.fanxb.bookmark.common.exception.CustomException;
import com.fanxb.bookmark.common.util.EsUtil;
import com.fanxb.bookmark.common.util.UserContextHolder;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
@ -19,7 +23,9 @@ import org.springframework.transaction.annotation.Transactional;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 类功能简述
@ -61,7 +67,7 @@ public class BookmarkService {
}
int count = 0;
// 將要插入es的书签数据放到list中,最后一次插入尽量避免mysql回滚了但是es插入了
List<BookmarkEs> insertEsList = new ArrayList<>();
List<EsEntity> insertEsList = new ArrayList<>();
for (int i = 0, length = elements.size(); i < length; i++) {
if (i == 0) {
Elements firstChildren = elements.get(0).child(1).children();
@ -73,6 +79,7 @@ public class BookmarkService {
dealBookmark(userId, elements.get(i), path, sortBase + count + i - 1, insertEsList);
}
}
esUtil.insertBatch(EsConstant.BOOKMARK_INDEX, insertEsList);
}
/**
@ -84,7 +91,7 @@ public class BookmarkService {
* @author fanxb
* @date 2019/7/8 14:49
*/
private void dealBookmark(int userId, Element ele, String path, int sort, List<BookmarkEs> insertList) {
private void dealBookmark(int userId, Element ele, String path, int sort, List<EsEntity> insertList) {
if (!DT.equalsIgnoreCase(ele.tagName())) {
return;
}
@ -95,7 +102,7 @@ public class BookmarkService {
, Long.valueOf(first.attr("add_date")) * 1000, sort);
//存入数据库
insertOne(node);
insertList.add(new BookmarkEs(node));
insertList.add(new EsEntity<>(node.getBookmarkId().toString(), new BookmarkEs(node)));
} else {
//说明为文件夹
Bookmark node = new Bookmark(userId, path, first.ownText(), Long.valueOf(first.attr("add_date")) * 1000, sort);
@ -111,7 +118,6 @@ public class BookmarkService {
for (int i = 0, size = children.size(); i < size; i++) {
dealBookmark(userId, children.get(i), childPath, sortBase + i + 1, insertList);
}
esUtil.insertBatch(EsConstant.BOOKMARK_INDEX, insertList);
}
}
@ -161,13 +167,18 @@ public class BookmarkService {
*/
@Transactional(rollbackFor = Exception.class)
public void batchDelete(int userId, List<Integer> folderIdList, List<Integer> bookmarkIdList) {
Set<Integer> set = new HashSet<>();
for (Integer item : folderIdList) {
set.addAll(bookmarkDao.getChildrenBookmarkId(userId, item));
bookmarkDao.deleteUserFolder(userId, item);
bookmarkIdList.add(item);
}
if (bookmarkIdList.size() > 0) {
bookmarkDao.deleteUserBookmark(userId, bookmarkIdList);
}
set.addAll(bookmarkIdList);
//es 中批量删除
esUtil.deleteBatch(EsConstant.BOOKMARK_INDEX, set);
}
/**
@ -193,7 +204,8 @@ public class BookmarkService {
}
//如果是书签插入到es中
if (bookmark.getType() == 0) {
esUtil.insertOne(EsConstant.BOOKMARK_INDEX, new BookmarkEs(bookmark));
esUtil.insertOrUpdateOne(EsConstant.BOOKMARK_INDEX,
new EsEntity<>(bookmark.getBookmarkId().toString(), new BookmarkEs(bookmark)));
}
return bookmark;
}
@ -211,7 +223,8 @@ public class BookmarkService {
bookmark.setUserId(userId);
bookmarkDao.editBookmark(bookmark);
if (bookmark.getType() == 0) {
esUtil.insertOne(EsConstant.BOOKMARK_INDEX, new BookmarkEs(bookmark));
esUtil.insertOrUpdateOne(EsConstant.BOOKMARK_INDEX,
new EsEntity<>(bookmark.getBookmarkId().toString(), new BookmarkEs(bookmark)));
}
}
@ -234,4 +247,23 @@ public class BookmarkService {
bookmarkDao.updatePathAndSort(userId, body.getBookmarkId(), body.getTargetPath(), body.getSort());
}
/**
* Description: 根据context搜索
*
* @param userId userId
* @param context context
* @author fanxb
* @date 2019/7/25 10:45
*/
public List<BookmarkEs> searchUserBookmark(int userId, String context) {
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.termQuery("userId", userId));
boolQueryBuilder.must(QueryBuilders.multiMatchQuery(context, "name", "url"));
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.size(5);
builder.query(boolQueryBuilder);
List<BookmarkEs> list = esUtil.search(EsConstant.BOOKMARK_INDEX, builder, BookmarkEs.class);
return list;
}
}

View File

@ -68,6 +68,17 @@
WHERE bookmarkId = #{folderId}) a);
</delete>
<select id="getChildrenBookmarkId" resultType="integer">
select bookmarkId
from bookmark
where
userId = #{userId}
and path LIKE (SELECT a.path
FROM (SELECT CONCAT(path, '.', '${folderId}', '%') AS path
FROM bookmark
WHERE bookmarkId = #{folderId}) a);
</select>
<delete id="deleteUserBookmark">
delete from bookmark where userId = #{userId} and bookmarkId in
<foreach collection="bookmarkIds" item="item" open="(" close=")" separator=",">

View File

@ -17,12 +17,10 @@ public class EsConstant {
/**
* 创建bookmark index语句
*/
public static final String CREATE_BOOKMARK_INDEX = "{" +
"\"properties\": {\n" +
public static final String CREATE_BOOKMARK_INDEX = "{\n" +
" \"properties\": {\n" +
" \"userId\":{\n" +
" \"type\":\"integer\",\n" +
" \"store\": true,\n" +
" \"index\":false\n" +
" \"type\":\"integer\"\n" +
" },\n" +
" \"name\":{\n" +
" \"type\":\"text\",\n" +
@ -31,8 +29,10 @@ public class EsConstant {
" },\n" +
" \"url\":{\n" +
" \"type\":\"text\",\n" +
" \"term_vector\": \"with_positions_offsets\"\n" +
" \"index\": true,\n" +
" \"analyzer\": \"ik_max_word\",\n" +
" \"search_analyzer\": \"ik_smart\"\n" +
" }\n" +
" }" +
"}";
" }\n" +
" }";
}

View File

@ -10,15 +10,15 @@ import lombok.Data;
* @date 2019/7/24 17:37
*/
@Data
public class EsInsertEntity<T> {
public final class EsEntity<T> {
private String id;
private T data;
public EsInsertEntity() {
public EsEntity() {
}
public EsInsertEntity(String id, T data) {
public EsEntity(String id, T data) {
this.data = data;
this.id = id;
}

View File

@ -2,12 +2,15 @@ package com.fanxb.bookmark.common.util;
import com.alibaba.fastjson.JSON;
import com.fanxb.bookmark.common.constant.EsConstant;
import com.fanxb.bookmark.common.entity.EsInsertEntity;
import com.fanxb.bookmark.common.entity.EsEntity;
import com.fanxb.bookmark.common.exception.CustomException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
@ -16,12 +19,14 @@ import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.lang.ref.ReferenceQueue;
import java.net.Authenticator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
@ -84,15 +89,14 @@ public class EsUtil {
}
/**
* Description: 插入一条记录
* Description: 插入/更新一条记录
*
* @param index index
* @param id id
* @param o o
* @param entity 对象
* @author fanxb
* @date 2019/7/24 15:02
*/
public void insertOne(String index, EsInsertEntity entity) {
public void insertOrUpdateOne(String index, EsEntity entity) {
IndexRequest request = new IndexRequest(index);
request.id(entity.getId());
request.source(JSON.toJSONString(entity.getData()), XContentType.JSON);
@ -111,9 +115,10 @@ public class EsUtil {
* @author fanxb
* @date 2019/7/24 17:38
*/
public void insertBatch(String index, List<? extends EsInsertEntity> list) {
public void insertBatch(String index, List<EsEntity> list) {
BulkRequest request = new BulkRequest();
list.forEach(item -> request.add(new IndexRequest(index).id(item.getId()).source(JSON.toJSONString(item.getData()))));
list.forEach(item -> request.add(new IndexRequest(index).id(item.getId())
.source(JSON.toJSONString(item.getData()), XContentType.JSON)));
try {
client.bulk(request, RequestOptions.DEFAULT);
} catch (Exception e) {
@ -121,6 +126,50 @@ public class EsUtil {
}
}
/**
* Description: 批量删除
*
* @param index index
* @param idList 待删除列表
* @author fanxb
* @date 2019/7/25 14:24
*/
public <T> void deleteBatch(String index, Collection<T> idList) {
BulkRequest request = new BulkRequest();
idList.forEach(item -> request.add(new DeleteRequest(index, item.toString())));
try {
client.bulk(request, RequestOptions.DEFAULT);
} catch (Exception e) {
throw new CustomException(e);
}
}
/**
* Description: 搜索
*
* @param index index
* @param builder 查询参数
* @param c 结果类对象
* @return java.util.ArrayList
* @author fanxb
* @date 2019/7/25 13:46
*/
public <T> List<T> search(String index, SearchSourceBuilder builder, Class<T> c) {
SearchRequest request = new SearchRequest(index);
request.source(builder);
try {
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
List<T> res = new ArrayList<>(hits.length);
for (SearchHit hit : hits) {
res.add(JSON.parseObject(hit.getSourceAsString(), c));
}
return res;
} catch (Exception e) {
throw new CustomException(e);
}
}
public static void main(String[] args) throws Exception {
EsUtil util = new EsUtil();