无聊啊,写一写,微信聊天机器人


1.sql数据表建立:

一开始使用varchar型的,后来感觉不行,只有重新写成int 自增的,自增在数据库里设置吧

CREATE TABLE CHATMAN_KNOWLEDGE(
      K_ID INTEGER NOT NULL,
      QUESTION VARCHAR(2000),
      ANSWER VARCHAR(8000),
      CATEGORY INT,
      PRIMARY KEY(K_ID)
);
alter tablle CHATMAN_KNOWLEDGE
 add id INTEGER ;
CREATE TABLE CHATMAN_KNSUB(
KN_ID INTEGER  identity(1,1) primary key,    --主键自增长
K_ID INTEGER,
ANSWER VARCHAR(8000)
/*PRIMARY KEY(KN_ID)*/
)


CREATE TABLE CHATMAN_JOKE(
J_ID VARCHAR(32),
CONTENT VARCHAR(5000),
PRIMARY KEY(J_ID)
)


CREATE TABLE CHATMAN_CHAT_LOG(
CL_ID VARCHAR(32) NOT NULL,
W_ID VARCHAR(100) NOT NULL,
CREATE_TIME DATETIME,
REG_MSG VARCHAR(2000),
RESP_MSG VARCHAR(2000),
CHAT_CATEGORY INT,
PRIMARY KEY(CL_ID)
)


2.数据库crud

3.服务chatService

package com.dm.wx.service;


import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Random;


import com.dm.chatman.domain.ChatLog;
import com.dm.chatman.domain.Knowledge;
import com.dm.chatman.service.ChatLogService;
import com.dm.chatman.service.JokeService;
import com.dm.chatman.service.KnowledgeService;
import com.dm.chatman.service.KnsubService;
import com.dm.core.service.BaseService;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;


import org.wltea.analyzer.lucene.IKAnalyzer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.apache.lucene.util.Version;


import java.io.File;
import java.util.List;


/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: 15-5-25
 * Time: 上午6:21
 * To change this template use File | Settings | File Templates.
 */
@Service("wxChatService")
@Transactional(isolation = Isolation.READ_COMMITTED, readOnly = true, rollbackFor = Throwable.class)
public class ChatService extends BaseService {
        @Autowired
    @Qualifier("chatmanKnowledgeService")
    private KnowledgeService knowledgeService;
     @Autowired
    @Qualifier("chatmanJokeService")
    private JokeService jokeService;
        @Autowired
    @Qualifier("chatmanChatLogService")
    private ChatLogService chatLogService;


        @Autowired
    @Qualifier("chatmanKnsubService")
    private KnsubService knsubService;
    public static String getIndexDir() {
// 得到.class文件所在路径(WEB-INF/classes/)
String classpath = ChatService.class.getResource("/").getPath();
// 将classpath中的%20替换为空格
classpath = classpath.replaceAll("%20", " ");
// 索引存储位置:WEB-INF/classes/index/
return classpath + "index/";
}
    /**
* 创建索引
*/
public  void createIndex() throws Exception{
// 取得问答知识库中的所有记录
List<Knowledge> knowledgeList = knowledgeService.list();
Directory directory = null;
IndexWriter indexWriter = null;
try {
directory = FSDirectory.open(new File(getIndexDir()));
IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_46, new IKAnalyzer(true));
indexWriter = new IndexWriter(directory, iwConfig);
Document doc = null;
// 遍历问答知识库创建索引
for (Knowledge knowledge : knowledgeList) {
doc = new Document();
// 对question进行分词存储
                doc = new Document();
// 对question进行分词存储
doc.add(new TextField("question", knowledge.getQuestion(), Store.YES));
// 对id、answer和category不分词存储
doc.add(new IntField("id", knowledge.getK_id(), Store.YES));
doc.add(new StringField("answer", knowledge.getAnswer(), Store.YES));
doc.add(new IntField("category", knowledge.getCategory(), Store.YES));
indexWriter.addDocument(doc);
}
indexWriter.close();
directory.close();
} catch (Exception e) {
e.printStackTrace();
}
}
    /**
* 从索引文件中根据问题检索答案
*
* @param content
* @return Knowledge
*/
@SuppressWarnings("deprecation")
private static Knowledge searchIndex(String content) {
Knowledge knowledge = null;
try {
Directory directory = FSDirectory.open(new File(getIndexDir()));
IndexReader reader = IndexReader.open(directory);
IndexSearcher searcher = new IndexSearcher(reader);
// 使用查询解析器创建Query
QueryParser questParser = new QueryParser(Version.LUCENE_46, "question", new IKAnalyzer(true));
Query query = questParser.parse(QueryParser.escape(content));
// 检索得分最高的文档
TopDocs topDocs = searcher.search(query, 1);
if (topDocs.totalHits > 0) {
knowledge = new Knowledge();
ScoreDoc[] scoreDoc = topDocs.scoreDocs;
for (ScoreDoc sd : scoreDoc) {
Document doc = searcher.doc(sd.doc);
knowledge.setK_id(doc.getField("id").numericValue().intValue());
knowledge.setQuestion(doc.get("question"));
knowledge.setAnswer(doc.get("answer"));
knowledge.setCategory(doc.getField("category").numericValue().intValue());
}
}
reader.close();
directory.close();
} catch (Exception e) {
knowledge = null;
e.printStackTrace();
}
return knowledge;
}


/**
* 聊天方法(根据question返回answer)
*
* @param openId 用户的OpenID
* @param createTime 消息创建时间
* @param question 用户上行的问题
* @return answer
*/
public  String chat(String openId, String createTime, String question) throws Exception{
String answer = null;
int chatCategory = 0;
Knowledge knowledge = searchIndex(question);
// 找到匹配项
if (null != knowledge) {
// 笑话
if (2 == knowledge.getCategory()) {
answer = jokeService.querymyJoke().getContent();
chatCategory = 2;
}
// 上下文
else if (3 == knowledge.getCategory()) {
// 判断上一次的聊天类别
int category = chatLogService.getLastCategory(openId).getChat_category();
// 如果是笑话,本次继续回复笑话给用户
if (2 == category) {
answer = jokeService.querymyJoke().getContent();
chatCategory = 2;
} else {
answer = knowledge.getAnswer();
chatCategory = knowledge.getCategory();
}
}
// 普通对话
else {
answer = knowledge.getAnswer();
// 如果答案为空,根据知识id从问答知识分表中随机获取一条
if ("".equals(answer))
answer = knsubService.getKnowledSub(knowledge.getK_id()).getAnswer();
chatCategory = 1;
}
}
// 未找到匹配项
else {
answer = getDefaultAnswer();
chatCategory = 0;
}
// 保存聊天记录
        ChatLog chatLog = new ChatLog();
        chatLog.setW_id(openId);
        chatLog.setCreate_time(new Date());
        chatLog.setReg_msg(question);
        chatLog.setResp_msg(answer);
        chatLog.setChat_category(chatCategory);
        chatLogService.create(chatLog);


return answer;
}


/**
* 随机获取一个默认的答案
*
* @return
*/
private static String getDefaultAnswer() {
String []answer = {
"要不我们聊点别的?",
"恩?你到底在说什么呢?",
"没有听懂你说的,能否换个说法?",
"虽然不明白你的意思,但我却能用心去感受",
"听的我一头雾水,阁下的知识真是渊博呀,膜拜~",
"真心听不懂你在说什么,要不你换种表达方式如何?",
"哎,我小学语文是体育老师教的,理解起来有点困难哦",
"是世界变化太快,还是我不够有才?为何你说话我不明白?"
};
return answer[getRandomNumber(answer.length)];
}


/**
* 随机生成 0~length-1 之间的某个值
*
* @return int
*/
private static int getRandomNumber(int length) {
Random random = new Random();
return random.nextInt(length);
}
}

4.配置索引

   private ChatService chatService;
    public void init(ServletConfig config) throws ServletException {
        System.out.print("初始化servelt成功");
        File indexDir = new File(ChatService.getIndexDir());
// 如果索引目录不存在则创建索引
if (!indexDir.exists()) {
             try{
chatService.createIndex();
             }catch (Exception e){
                 System.out.print("创建索引异常");
             }
        }
        this.config = config;
    }

5.设置web.xnl每次首先加载

    <servlet>
        <servlet-name>coreServlet</servlet-name>
        <servlet-class>com.dm.wx.HttpServletProxy</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>
        <!--<servlet>-->
        <!--<servlet-name>coreServlet</servlet-name>-->
        <!--<servlet-class>com.dm.wx.controller.CoreServlet</servlet-class>-->
    <!--</servlet>-->
    <servlet-mapping>
        <servlet-name>coreServlet</servlet-name>
        <url-pattern>/coreServlet</url-pattern>
    </servlet-mapping>

6.添加和修改数据表,删除索引,重新启动就可以加载添加的数据索引了,自动化查询时挺有用的。

大家可参考我的博客:

我的博客:115.159.110.224

我的微信公众号:my528xx

公众号二维码:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jimin_zhou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值