最近有个业务场景需要查询mongoDB的相似度,由于之前没做过,所以从头研究,现将自己的编码过程做以下分享,有什么不合理的希望各位大佬指正。
1、前提是需要将mongo里面需要查询的字段建立索引,并存入mongo中:db.chinese_test.createIndex( { fc_text: "text" } );
2、首先需要对输入的查询文本进行分词操作,这里我用的是ANSJ分词器:
public class QuestionParticipleByANSJ { public static String doParticiple(String question) { if (StringUtils.isEmpty(question)) { return null; } BeanMap beanMap = BeanMap.create(ToAnalysis.parse(question)); StringBuffer stringBuffer = new StringBuffer(); for (Object key : beanMap.keySet()) { List list = (List)beanMap.get(key); for (int i = 0; i < list.size(); i++) { String str = list.get(i).toString(); String[] split = str.split("/"); String word = split[0].replaceAll("\\pP|\\pS", ""); if (word.isEmpty()){ continue; } stringBuffer.append(word).append(" "); } } return stringBuffer.toString().trim(); }
// 这里是测试分词效果 public static void main(String[] args) { String question = "中华人民共和国今天成立了!!@#¥%……&*()我是一只大大的的 "; String obj = doParticiple(question); System.out.println(obj); } }
分词效果:
3、进行查询
@Override public List<String> querySimFaqTitle(String faqTitle,String spaceCode) { // 将输入问题进行分词 String str = QuestionParticipleByANSJ.doParticiple(faqTitle); // mongoDB全文索引查询匹配度 MongoDatabase db = mongoTemplate.getDb(); MongoCollection<Document> collection = db.getCollection("faq_details_test"); Bson searchQuery = Filters.text(str); Bson projection = Projections.metaTextScore("score"); Bson sortQuery = Sorts.metaTextScore("score"); FindIterable<Document> limit = collection.find(searchQuery) .projection(projection) .sort(sortQuery) .limit(5); // .first();// 取第一条 //若是需要构建条件查询: //FindIterable<Document> limit = collection.find(and(searchQuery, //in(“intention_code”, //codeList))) //.projection(projection) //.sort(sortQuery) //.limit(5); System.out.println(limit); List<String> objects = new ArrayList<>(); for (Document document:limit){ if ((Integer) document.get("faq_status")==1&&document.get("faq_space_code").toString().equals(spaceCode)){ objects.add(document.get("faq_title").toString()); } } return objects; }
查询结果:
这里我只返回了需要的字段,根据查询的score值进行从大到小排序。