您的位置:首页 > 移动开发 > 微信开发

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

2015-05-27 22:21 471 查看
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

公众号二维码:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: