deploy-jar-template/pom.xml
@@ -17,6 +17,13 @@ </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.iplatform</groupId> <artifactId>iplatform-base</artifactId> @@ -198,6 +205,12 @@ <!-- <artifactId>iplatform-report</artifactId>--> <!-- </dependency>--> <!-- 2024-03-28 æµè¯ä¸é®å¡«å·¥åï¼éè¦è天åæç¸ä¼¼åº¦ --> <dependency> <groupId>com.walkersoft</groupId> <artifactId>walker-support-milvus</artifactId> </dependency> </dependencies> <build> deploy-jar-template/src/main/java/com/iplatform/api/MilvusChatApi.java
New file @@ -0,0 +1,217 @@ package com.iplatform.api; import com.iplatform.base.SystemController; import com.iplatform.milvus.EventVo; import com.iplatform.milvus.MilvusEngine; import com.iplatform.milvus.ParamList; import com.iplatform.milvus.service.EventServiceImpl; import com.walker.infrastructure.utils.StringUtils; import com.walker.web.ResponseValue; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.concurrent.TimeUnit; @RestController @RequestMapping("/test/milvus") public class MilvusChatApi extends SystemController { private EventServiceImpl eventService; private RestTemplate restTemplate; private MilvusEngine milvusEngine; private Long existId = 4048L; private boolean isBreak = false; private static final String URL_EMBEDDING = "http://120.26.128.84:7003/ai/text/embedding"; private static final String URL_MILVUS = "120.26.128.84"; @Autowired public MilvusChatApi(EventServiceImpl eventService, RestTemplate restTemplate){ this.eventService = eventService; this.restTemplate = restTemplate; if(this.milvusEngine == null){ MilvusEngine engine = new MilvusEngine(URL_MILVUS, 19530); this.milvusEngine = engine; logger.info("milvus engine ok!"); } } @RequestMapping("/embedding") public ResponseValue testHttpEmbedding(){ List<EventVo> data = new ArrayList(8); EventVo eventVo = new EventVo(); eventVo.setContent("第ä¸å¥"); data.add(eventVo); eventVo = new EventVo(); eventVo.setContent("第äºå¥"); data.add(eventVo); boolean success = this.acquireEmbedding(data); this.milvusEngine.insertTestData(); return ResponseValue.success("ç»ææ¯ï¼" + success); } @RequestMapping("/write") public ResponseValue testWriteMilvus(){ Collection<EventVo> eventVoList = this.acquireEventVoList(); if(eventVoList == null){ return ResponseValue.error("没æå è½½å°æ°æ®"); } logger.info("å è½½äº event vo: {}个", eventVoList.size()); new Thread(new WriteTask(eventVoList)).start(); return ResponseValue.success(); } @RequestMapping("/query") public ResponseValue testQueryMilvus(String text){ return ResponseValue.success(); } private boolean acquireEmbedding(List<EventVo> batchData){ ParamList paramList = new ParamList(); for(EventVo eventVo : batchData){ paramList.add(eventVo.getContent()); } try{ ResponseEntity<ResponseValue> responseEntity = this.restTemplate.postForEntity(URL_EMBEDDING, paramList, ResponseValue.class); if(responseEntity.getStatusCode() == HttpStatus.OK){ List<List<Float>> data = (List<List<Float>>)responseEntity.getBody().getData(); // double[] one = null; List<Float> vector = null; for(int i=0; i<data.size(); i++){ vector = data.get(i); // one = new double[vector.size()]; // for(int j=0; j< vector.size(); j++){ // one[j] = vector.get(j); // } // logger.debug("data = {}", vector); // logger.debug("class type = {}", vector.getClass().getName()); batchData.get(i).setEmbedding(this.transfer2FloatList(vector)); } return true; } else { logger.error("http è¿åé误ï¼{}", responseEntity.getBody()); } return false; } catch (Exception cause){ logger.error("è·ååéåºç°é误ï¼{}" + cause.getMessage(), cause); return false; } } private List<Float> transfer2FloatList(List<?> list){ List<Float> vector = new ArrayList<>(768); for(int i=0; i<list.size(); i++){ vector.add(Float.parseFloat(list.get(i).toString())); } return vector; } private class WriteTask implements Runnable{ private Collection<EventVo> eventVoList; public WriteTask(Collection<EventVo> eventVoList){ this.eventVoList = eventVoList; } @Override public void run() { logger.info(".......... start task ..."); // å¤ä½ç¶æ isBreak = false; int count = 0; List<EventVo> batchData = new ArrayList<>(); for(EventVo eventVo : this.eventVoList){ // å·²åå¨ä¸æ¬¡å 载记å½ï¼å·²åå ¥çä¸å¨éæ°å¤ç if(existId != null && eventVo.getId() < existId.longValue()){ continue; } if(isBreak){ break; } if(count == 0){ logger.info("1) å¼å§ï¼æç»§ç»ï¼éé第 {} è®°å½", eventVo.getId()); } if(count >= 8){ // 触å䏿¬¡æ¹éåå ¥ logger.info("2) 触å䏿¬¡è°ç¨ï¼{}", batchData.get(7).getId()); try { boolean successEmbedding = acquireEmbedding(batchData); if(!successEmbedding){ logger.error("è·ååé失败ï¼ä»»å¡ç»æ"); break; } // è·ååéï¼åå ¥æ°æ®åº milvusEngine.insertEventVoList(batchData); } catch (Exception ex){ logger.error("error = " + ex.getMessage(), ex); // existId = eventVo.getId(); isBreak = true; logger.error("3) ééä»»å¡å¼å¸¸ï¼ å½å id = {}", existId == null ? "" : existId); break; } finally { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } // æ¸ çæ¬æ¬¡æ°æ® batchData.clear(); count = 0; } batchData.add(eventVo); count ++; } logger.info(".......... end task ..."); } } private Collection<EventVo> acquireEventVoList(){ List<EventVo> data = null; // if(this.isBreak){ // data = this.eventService.queryEventAll(existId); // } else { // data = this.eventService.queryEventAll(null); // } data = this.eventService.queryEventAll(null); if(StringUtils.isEmptyList(data)){ return null; } // è¿æ»¤æ content éå¤çæ°æ®è®°å½ LinkedHashMap<String, EventVo> cache = new LinkedHashMap(); EventVo temp = null; for(EventVo e : data){ temp = cache.get(e.getContent()); if(temp == null){ cache.put(e.getContent(), e); } } return cache.values(); } } deploy-jar-template/src/main/java/com/iplatform/milvus/EventVo.java
New file @@ -0,0 +1,54 @@ package com.iplatform.milvus; import java.util.List; public class EventVo { public long getId() { return id; } public void setId(long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public List<Float> getEmbedding() { return embedding; } public void setEmbedding(List<Float> embedding) { this.embedding = embedding; } public String getAnswer() { return answer; } public void setAnswer(String answer) { this.answer = answer; } private long id; private String title; private String content; // private double[] embedding; // private List<Double> embedding; private List<Float> embedding; private String answer; // ä¸åå ¥milvusï¼ä» å¨ç¼åä¸ç¨äºè¿åé®çç»æ } deploy-jar-template/src/main/java/com/iplatform/milvus/MilvusEngine.java
New file @@ -0,0 +1,152 @@ package com.iplatform.milvus; import com.walker.infrastructure.utils.StringUtils; import com.walker.support.milvus.DataSet; import com.walker.support.milvus.DataType; import com.walker.support.milvus.FieldType; import com.walker.support.milvus.MetricType; import com.walker.support.milvus.OperateService; import com.walker.support.milvus.Table; import com.walker.support.milvus.engine.DefaultOperateService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; public class MilvusEngine { protected final transient Logger logger = LoggerFactory.getLogger(this.getClass()); public MilvusEngine(String ip, int port){ DefaultOperateService service = new DefaultOperateService(); service.connect(ip, port); this.operateService = service; logger.info("connect milvus: {}:{}", ip, port); } public void close(){ if(this.operateService != null){ this.operateService.close(); } } /** * åå»ºè¡¨ï¼æµè¯ä»è天ä¸é®æåå·¥åå 容使ç¨ã * <pre> * 1) ä»åå²å·¥åæ°æ®ä¸ï¼æ¶éç¨æ·æé®å å®¹ï¼æ´çå°è¡¨ä¸ * 2) æè¿äºæ°æ®éè¿åé转åï¼åå ¥milvusæ°æ®åºã * </pre> * @date 2024-03-28 */ public void createChatSimilarTable(){ Table chatSimilarTable = new Table(); chatSimilarTable.setCollectionName("chat_similar"); chatSimilarTable.setDescription("è天æåå·¥åæè¦å岿°æ®"); chatSimilarTable.setShardsNum(1); chatSimilarTable.setDimension(768); // è¿ä¸ªæ¯æ ¹æ®ä½¿ç¨å鿍¡å维度å®ç // è®¾ç½®åæ®µ FieldType id = FieldType.newBuilder() .withName("id").withPrimaryKey(true).withMaxLength(18).withDataType(DataType.Long).build(); FieldType title = FieldType.newBuilder() .withName("title").withPrimaryKey(false).withMaxLength(180).withDataType(DataType.VarChar).build(); FieldType content = FieldType.newBuilder() .withName("content").withPrimaryKey(false).withMaxLength(255).withDataType(DataType.VarChar).build(); FieldType answer = FieldType.newBuilder() .withName("answer").withPrimaryKey(false).withMaxLength(255).withDataType(DataType.VarChar).build(); FieldType embedding = FieldType.newBuilder() .withName("embedding").withPrimaryKey(false).withDataType(DataType.FloatVector).withDimension(768).build(); List<FieldType> fieldTypeList = new ArrayList<>(8); fieldTypeList.add(id); fieldTypeList.add(title); fieldTypeList.add(content); fieldTypeList.add(answer); fieldTypeList.add(embedding); chatSimilarTable.setFieldTypes(fieldTypeList); this.operateService.createTable(chatSimilarTable); logger.info("åå»ºäº table = {}", chatSimilarTable.getCollectionName()); // åå»ºç´¢å¼ this.operateService.createIndex(chatSimilarTable.getCollectionName() , "embedding", "HNSW", "{\"nlist\":16384, \"efConstruction\":128, \"M\":8}", MetricType.NLP); logger.info("åå»ºäº index = {}", chatSimilarTable.getCollectionName() + "_index"); } public void dropChatSimilarTable(){ this.operateService.dropTable("chat_similar"); } public void insertTestData(){ DataSet dataSet = new DataSet(); dataSet.setTableName("chat_similar"); List<List<Float>> vectorList = new ArrayList<>(); vectorList.add(Arrays.asList(mockVector)); vectorList.add(Arrays.asList(mockVector)); Map<String, List<?>> fieldMap = new HashMap(); fieldMap.put("id", Arrays.asList(new Long[]{1L, 2L})); fieldMap.put("title", Arrays.asList(new String[]{"第ä¸ä¸ªæ é¢", "第äºä¸ªæ é¢"})); fieldMap.put("content", Arrays.asList(new String[]{"第ä¸ä¸ªå 容", "2222"})); fieldMap.put("answer", Arrays.asList(new String[]{"第ä¸ä¸ªçæ¡", "22222222"})); fieldMap.put("embedding", vectorList); dataSet.setFields(fieldMap); this.operateService.insertDataSet(dataSet); logger.info("åå ¥äºæµè¯æ°æ®: {}", dataSet); } public void insertEventVoList(List<EventVo> batchData){ if(StringUtils.isEmptyList(batchData)){ return; } List<Long> ids = new ArrayList<>(8); List<String> titles = new ArrayList<>(8); List<String> contents = new ArrayList<>(8); List<String> answers = new ArrayList<>(8); List<List<Float>> vectorSet = new ArrayList<>(8); for(EventVo vo : batchData){ ids.add(vo.getId()); vectorSet.add(vo.getEmbedding()); if(StringUtils.isNotEmpty(vo.getTitle())){ titles.add(vo.getTitle()); } else { titles.add("none"); } if(StringUtils.isNotEmpty(vo.getAnswer())){ answers.add(vo.getAnswer()); } else { answers.add("none"); } if(vo.getContent().length() > 200){ contents.add(vo.getContent().substring(0, 200)); } else { contents.add(vo.getContent()); } } DataSet dataSet = new DataSet(); dataSet.setTableName("chat_similar"); Map<String, List<?>> fieldMap = new HashMap(); fieldMap.put("id", ids); fieldMap.put("title", titles); fieldMap.put("content", contents); fieldMap.put("answer", answers); fieldMap.put("embedding", vectorSet); dataSet.setFields(fieldMap); this.operateService.insertDataSet(dataSet); logger.info("åå ¥äº: {}", ids); } private OperateService operateService; // private Double[] mockVector = new Double[]{-0.051114246249198914, 0.889954432}; private Float[] mockVector = new Float[]{-0.051114246249198914f, 0.889954432f}; } deploy-jar-template/src/main/java/com/iplatform/milvus/ParamList.java
New file @@ -0,0 +1,35 @@ package com.iplatform.milvus; import java.util.ArrayList; import java.util.List; /** * 请æ±åæ°ï¼è°ç¨åéçææå¡ã * @date 2024-03-29 */ public class ParamList { public void add(String text){ if(this.list == null){ this.list = new ArrayList<>(8); } this.list.add(text); } public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } private List<String> list; @Override public String toString() { return "ParamList{" + "list=" + list + '}'; } } deploy-jar-template/src/main/java/com/iplatform/milvus/service/EventServiceImpl.java
New file @@ -0,0 +1,46 @@ package com.iplatform.milvus.service; import com.iplatform.milvus.EventVo; import com.walker.jdbc.service.BaseServiceImpl; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; @Service public class EventServiceImpl extends BaseServiceImpl { private final EventVoMapper eventVoMapper = new EventVoMapper(); public List<EventVo> queryEventAll(Long existId){ if(existId == null){ return this.select("select * from event_history order by id asc", new Object[]{}, this.eventVoMapper); } else { return this.select("select * from event_history where id > ? order by id asc", new Object[]{existId}, this.eventVoMapper); } } private static class EventVoMapper implements RowMapper<EventVo> { @Override public EventVo mapRow(ResultSet rs, int rowNum) throws SQLException { EventVo e = new EventVo(); e.setId(rs.getLong("id")); e.setContent(rs.getString("content")); String title = rs.getString("title"); if(title.length() > 200){ title = title.substring(0, 200); } e.setTitle(title); if(rs.getObject("answer") != null){ String answer = rs.getString("answer"); if(answer.length() > 180){ answer = answer.substring(0,180); } e.setAnswer(answer); } return e; } } } deploy-jar-template/src/main/resources/application-dev.yml
@@ -424,11 +424,11 @@ # 空é²è¿æ¥æ°éï¼é»è®¤ï¼200个 max-idle-connections: 200 # è¿æ¥è¶ æ¶ï¼é»è®¤ï¼2ç§ connect-timeout-seconds: 2 connect-timeout-seconds: 20 # è¯»è¶ æ¶ï¼é»è®¤3ç§ read-timeout-seconds: 3 read-timeout-seconds: 30 # åè¶ æ¶ï¼é»è®¤3ç§ write-timeout-seconds: 3 write-timeout-seconds: 30 # éç¾¤æ¯æç¸å ³é ç½®ï¼2023-09-29 lb: deploy-jar-template/src/test/java/com/iplatform/milvus/TestMilvus.java
New file @@ -0,0 +1,37 @@ package com.iplatform.milvus; import org.junit.Test; import org.springframework.web.client.RestTemplate; public class TestMilvus { /** * å建è天䏿åå·¥åæè¦åè½ï¼milvusæµè¯è¡¨å建ã * <p>ç¬¬ä¸æ¥ï¼å建表åç´¢å¼</p> */ // @Test public void createTable(){ this.acquireMilvusEngine(); this.milvusEngine.createChatSimilarTable(); } /** * æµè¯ï¼åå ¥ä¸ä¸ªæ¨¡ææ°æ® */ // @Test public void insertTestMockData(){ this.acquireMilvusEngine(); this.milvusEngine.insertTestData(); } private void acquireMilvusEngine(){ if(this.milvusEngine == null){ MilvusEngine engine = new MilvusEngine("120.26.128.84", 19530); this.milvusEngine = engine; } } private RestTemplate restTemplate = new RestTemplate(); private MilvusEngine milvusEngine; } iplatform-file-server/src/main/java/com/iplatform/file/FileEngineFactory.java
@@ -256,6 +256,11 @@ if(StringUtils.isNotEmpty(fileUrlPrefixConfig)){ FileStoreUtils.fileStoreTypeUrlPrefix.put(FileStoreType.OssAli.getIndex(), fileUrlPrefixConfig); } // 2024-02-23 s3对象ä¸ä¼ fileUrlPrefixConfig = this.getFileUrlPrefix(FileStoreType.OssAws.getIndex()); if(StringUtils.isNotEmpty(fileUrlPrefixConfig)){ FileStoreUtils.fileStoreTypeUrlPrefix.put(FileStoreType.OssAws.getIndex(), fileUrlPrefixConfig); } } /** iplatform-file-server/src/main/java/com/iplatform/file/util/FileStoreUtils.java
@@ -38,6 +38,8 @@ uploadUrl = ArgumentsConstants.CONFIG_AL_UPLOAD_URL; } else if(fileStoreType.equals("4") || fileStoreType.equals(FileStoreType.INDEX_OSS_TX)){ uploadUrl = ArgumentsConstants.CONFIG_TX_UPLOAD_URL; } else if(fileStoreType.equals("5") || fileStoreType.equals(FileStoreType.INDEX_OSS_AWS)){ uploadUrl = ArgumentsConstants.CONFIG_S3_UPLOAD_URL; } else if(fileStoreType.equals(FileStoreType.INDEX_FTP)){ // throw new UnsupportedOperationException("ftpå卿¹å¼æªè®¾ç½®åæ°ï¼"); uploadUrl = ArgumentsConstants.CONFIG_FTP_UPLOAD_URL; iplatform-pay-server/doc/Ö§¸¶ÖÐ̨Éè¼Æ.EAPBinary files differ