政网站首页怎么做试,深圳网站建设主页,昆明网络推广公司排名,seo项目经理探索DataLoom的智能问数功能#xff1a;简化数据库查询
在数据驱动的决策制定中#xff0c;数据库查询是获取洞察的关键步骤。但是#xff0c;传统的数据库查询方法往往复杂且技术性强#xff0c;这限制了非技术用户的使用。DataLoom的智能问数功能正是为了解决这一问题而…探索DataLoom的智能问数功能简化数据库查询
在数据驱动的决策制定中数据库查询是获取洞察的关键步骤。但是传统的数据库查询方法往往复杂且技术性强这限制了非技术用户的使用。DataLoom的智能问数功能正是为了解决这一问题而设计的。本文将详细介绍这一功能并展示其背后的代码实现。
DataLoom简介
DataLoom是一个创新的数据管理平台旨在通过提供直观的界面和强大的后端处理能力简化数据查询和分析过程。我们的目标是让数据查询变得简单让每个人都能轻松地从数据中获取洞察。
智能问数功能 智能问数是DataLoom的核心功能之一它允许用户通过自然语言输入查询请求系统会自动将其转换为SQL语句并执行。这一功能极大地降低了技术门槛使得即使是没有数据库背景的用户也能快速获取所需数据。
核心流程图 核心代码
ChatForSQLRequest类
Data
public class ChatForSQLRequest {/*** 模型Id*/private Long chatId;/*** 询问的数据*/private String question;
}这是一个简单的Java Bean类用于封装用户请求智能问数时发送的数据。它包含两个属性chatId模型Id和question询问的数据。
userChatForSQL方法
public void userChatForSQL(ChatForSQLRequest chatForSQLRequest, User loginUser) {Long chatId chatForSQLRequest.getChatId();String question chatForSQLRequest.getQuestion();// 1. 获取模型IDChat chat chatService.getById(chatId);ThrowUtils.throwIf(chat null, ErrorCode.PARAMS_ERROR, 不存在该助手);// 2. 获取数据源所有的元数据Long datasourceId chat.getDatasourceId();ListAskAIWithDataTablesAndFieldsRequest dataTablesAndFieldsRequests getAskAIWithDataTablesAndFieldsRequests(loginUser, datasourceId);// 3. 构造请求AI的输入String input buildAskAISQLInput(dataTablesAndFieldsRequests, question);// 4. 持久化消息ChatHistory user_q new ChatHistory();user_q.setChatRole(ChatHistoryRoleEnum.USER.getValue());user_q.setChatId(chatId);user_q.setModelId(chat.getModelId());user_q.setContent(question);chatHistoryService.save(user_q);// 5. 利用webSocket发送消息通知开始AskSQLWebSocketMsgVO askSQLWebSocketMsgVO new AskSQLWebSocketMsgVO();askSQLWebSocketMsgVO.setType(start);askSQLWebSocket.sendOneMessage(loginUser.getId(), askSQLWebSocketMsgVO);// 6. 询问AI获取返回的SQLString sql aiManager.doAskSQLWithKimi(input, LIMIT_RECORDS);// 7. 执行SQL并得到返回的结果QueryAICustomSQLVO queryAICustomSQLVO null;try {queryAICustomSQLVO buildUserChatForSqlVO(datasourceId, sql);} catch (Exception e) { // 防止异常发生前端还继续等待接收数据if (e instanceof SQLException) { // 记录异常queryAICustomSQLVO new QueryAICustomSQLVO();queryAICustomSQLVO.setSql(sql);ChatHistory chatHistory ChatHistory.builder().chatRole(ChatHistoryRoleEnum.MODEL.getValue()).chatId(chatId).modelId(chat.getModelId()).status(ChatHistoryStatusEnum.FAIL.getValue()).execMessage(查询异常).content(JSONUtil.toJsonStr(queryAICustomSQLVO)).build();chatHistoryService.updateById(chatHistory);}notifyMessageEnd(loginUser.getId());return;}// 8. 将查询的结果存放在数据库中ChatHistory chatHistory new ChatHistory();chatHistory.setChatRole(ChatHistoryRoleEnum.MODEL.getValue());chatHistory.setChatId(chatId);chatHistory.setModelId(chat.getModelId());// 9. 存储结果类JSON字符串chatHistory.setContent(JSONUtil.toJsonStr(queryAICustomSQLVO));try {chatHistoryService.save(chatHistory);} catch (Exception e) {notifyMessageEnd(loginUser.getId());return;}// 10. 利用webSocket发送消息通知AskSQLWebSocketMsgVO res AskSQLWebSocketMsgVO.builder().res(queryAICustomSQLVO.getRes()).columns(queryAICustomSQLVO.getColumns()).type(running).sql(sql).build();askSQLWebSocket.sendOneMessage(loginUser.getId(), res);// 11. 通知结束notifyMessageEnd(loginUser.getId());
}这个方法是处理用户SQL查询请求的核心逻辑。它执行以下步骤
验证模型ID是否存在。获取数据源的所有元数据。构造请求AI的输入。持久化用户的消息。通过WebSocket通知前端开始处理。询问AI获取返回的SQL语句。执行SQL并获取结果。将查询结果持久化。存储结果类为JSON字符串。通过WebSocket发送查询结果。通知查询结束。
getAskAIWithDataTablesAndFieldsRequests方法
/*** 查询对应数据源所有元数据表信息、表字段* param loginUser* param datasourceId* return*/
private ListAskAIWithDataTablesAndFieldsRequest getAskAIWithDataTablesAndFieldsRequests(User loginUser, Long datasourceId) {ListCoreDatasetTable tables coreDatasourceService.getTablesByDatasourceId(datasourceId, loginUser);ThrowUtils.throwIf(tables.isEmpty(), ErrorCode.PARAMS_ERROR, 数据源暂无数据);ListAskAIWithDataTablesAndFieldsRequest dataTablesAndFieldsRequests new ArrayList();tables.forEach(table - {// 查询所有字段LambdaQueryWrapperCoreDatasetTableField wrapper new LambdaQueryWrapper();wrapper.eq(CoreDatasetTableField::getDatasetTableId, table.getId());ListCoreDatasetTableField tableFields coreDatasetTableFieldService.list(wrapper);AskAIWithDataTablesAndFieldsRequest askAIWithDataTablesAndFieldsRequest AskAIWithDataTablesAndFieldsRequest.builder().tableId(table.getId()).tableComment(table.getName()).tableName(table.getTableName()).coreDatasetTableFieldList(tableFields).build();dataTablesAndFieldsRequests.add(askAIWithDataTablesAndFieldsRequest);});return dataTablesAndFieldsRequests;
}这个方法用于查询给定数据源的所有表信息和表字段。它遍历所有表为每个表查询字段信息并构建一个包含这些信息的请求列表。
buildAskAISQLInput方法
/*** 构造智能问数的问题* param dataTablesAndFieldsRequests 数据源元数据* param question* return* 示例* 分析需求%s,* [* {表名: %s, 表注释 %s, 字段列表:[{%s}、{%s}]}* {表名: %s, 表注释 %s, 字段列表:[{%s}、{%s}]}* ]*/
private String buildAskAISQLInput(ListAskAIWithDataTablesAndFieldsRequest dataTablesAndFieldsRequests, String question) {StringBuilder res new StringBuilder();// 1. 构造需求res.append(String.format(ANALYSIS_QUESTION, question));res.append(SPLIT);// 2. 构造表与字段信息StringBuilder tablesAndFields new StringBuilder();dataTablesAndFieldsRequests.forEach(tableAndFields - {// 构造当前表字段列表StringBuilder tableFieldsInfo new StringBuilder();ListCoreDatasetTableField fieldList tableAndFields.getCoreDatasetTableFieldList();fieldList.forEach(field - {tableFieldsInfo.append(String.format(FIELDS_INFO, field.getOriginName(), field.getName(), field.getType()));tableFieldsInfo.append(SPLIT);});// 构造当前表信息String tableFieldsInfoList String.format(LIST_INFO, tableFieldsInfo);tablesAndFields.append(String.format(TABLE_INFO, tableAndFields.getTableName(), tableAndFields.getTableComment(), tableFieldsInfoList));tableFieldsInfo.append(SPLIT);});res.append(String.format(TABLES_AND_FIELDS_PART, tablesAndFields));return res.toString();
}这个方法用于构造智能问数的问题。它将用户的问题和数据源的元数据结合起来形成一个格式化的字符串该字符串将作为AI的输入。
doAskSQLWithKimi方法
/*** 执行智能问数* param message 构造的输入* param limitSize select 结果限制的行数* return*/
public String doAskSQLWithKimi(String message, int limitSize) {String SQLPrompt 你是一个MySQL数据库专家专门负责根据查询需求得出SQL查询语句接下来我会按照以下固定格式给你提供内容 \n 分析需求:{分析需求或者目标} \n 所有的数据表元数据:[{数据库表名、表注释、数据库表的字段、注释以及类型}] \n 请根据这两部分内容按照以下指定格式生成内容(此外不要输出任何多余的开头、结尾、注释),并且只生成Select语句!!! 请严格按照数据表元数据中存在的数据表和字段不要查询不存在的表和字段\n 要求select的结果不超过 limitSize 行;ListMessage messages CollUtil.newArrayList(new Message(RoleEnum.system.name(), SQLPrompt),new Message(RoleEnum.user.name(), message));return moonshotAiClient.chat(moonshot-v1-32k,messages);
}这个方法用于执行智能问数。它构造一个包含分析需求和数据表元数据的消息然后通过调用AI客户端来获取SQL查询语句。
buildUserChatForSqlVO方法
/*** 执行SQL并封装智能问数返回类* param datasourceId 数据源id* param sql 执行sql* return 智能问数返回类*/
private QueryAICustomSQLVO buildUserChatForSqlVO(Long datasourceId, String sql) throws SQLException {return datasourceEngine.execSelectSqlToQueryAICustomSQLVO(datasourceId, sql);
}这个方法用于执行SQL语句并将结果封装到QueryAICustomSQLVO对象中。它调用execSelectSqlToQueryAICustomSQLVO方法传入数据源ID和SQL语句然后返回查询结果。
execSelectSqlToQueryAICustomSQLVO方法
/*** 执行SQL语句并将列集合和记录犯规* param datasourceId 数据源id* param sql sql语句* param parameters 参数* return*/
public QueryAICustomSQLVO execSelectSqlToQueryAICustomSQLVO(Long datasourceId, String sql, Object... parameters) throws SQLException {int dsIndex (int) (datasourceId % (dataSourceMap.size()));// 获取对应连接池DataSource dataSource dataSourceMap.get(dsIndex);QueryAICustomSQLVO queryAICustomSQLVO new QueryAICustomSQLVO();// 所有列ListString columns new ArrayList();// 所有结果ListMapString, Object res new ArrayList();Connection connection dataSource.getConnection();PreparedStatement preparedStatement connection.prepareStatement(sql);// Set parameters to prevent SQL injectionfor (int i 0; i parameters.length; i) {preparedStatement.setObject(i 1, parameters[i]);}ResultSet rs preparedStatement.executeQuery();// Execute the query or update// 处理查询结果ResultSetMetaData rsmd rs.getMetaData();int columnCount rsmd.getColumnCount();for (int i 1; i columnCount; i) {columns.add(rsmd.getColumnName(i));}while (rs.next()) {MapString, Object resMap new HashMap();for (int i 1; i columnCount; i) {resMap.put(rsmd.getColumnName(i), rs.getString(i));}res.add(resMap);}queryAICustomSQLVO.setSql(sql);queryAICustomSQLVO.setColumns(columns);queryAICustomSQLVO.setRes(res);return queryAICustomSQLVO;
}这个方法用于执行SQL查询并将结果集转换为一个包含列名和记录的QueryAICustomSQLVO对象。它使用PreparedStatement来设置参数执行查询并遍历结果集将每一行的数据存储到一个Map中然后将这些Map添加到结果列表中。
这些代码片段共同构成了DataLoom智能问数功能的核心实现。每个片段都扮演着处理用户请求、与数据库交互、以及与AI服务通信的重要角色。
未来展望
我们对DataLoom的未来充满期待。我们计划引入更多的智能功能这些功能将在下面的几篇文章中介绍例如智能仪表盘智能图表分析报告等
项目快速启动
见GitHubDataLoom 仓库见Gitee地址Gitee 仓库
如何贡献
如果你对 DataLoom 感兴趣并想做出贡献欢迎提交 issue 或 Pull Request。我们非常欢迎开发者一起加入共同改进这个项目。
GitHub 地址DataLoom 仓库Gitee地址Gitee 仓库你可以通过创建 Issue 来报告问题或通过提交 PR 来贡献代码。 希望这篇文章能够激发你对 DataLoom 项目的兴趣如果你喜欢这个项目请给我们一个 Star ⭐️这对我们来说意义重大
请持续关注后续文章也会发一些有关项目功能设计亮点介绍 项目地址DataLoom GitHub 仓库 项目问题通过下面的联系方式进行沟通 邮箱hardork163.com WX号: _hardork 如果需要项目文档可以联系WX号