|
@@ -25,6 +25,13 @@ var segment = new Segment();
|
|
|
// 使用默认的识别模块及字典,载入字典文件需要1秒,仅初始化时执行一次即可
|
|
|
segment.useDefault();
|
|
|
|
|
|
+let nodejieba = require('../../dict/jieba');
|
|
|
+
|
|
|
+let nameWeightMap ={
|
|
|
+ // '普通':-99
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
|
|
|
async function getOptions(data,compilation){//data 是预留对象,暂时不用
|
|
|
let compilationID = compilation._id;
|
|
@@ -105,6 +112,12 @@ async function getDataByCondition(data,compilation){
|
|
|
if (data.code) {
|
|
|
result = await getDataByCode(data.code, data);
|
|
|
if (result.totalSize > 0) return result;
|
|
|
+
|
|
|
+ //如果分类编码有结果,但是确没有匹配的条数,说明关键字没匹配上,直接返回没有信息价
|
|
|
+ if(result.allItems > 0 && result.totalSize === 0){
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
//编号匹配不上的情况:
|
|
@@ -127,16 +140,38 @@ async function getDataByCondition(data,compilation){
|
|
|
async function getDataByCode(code, data) {
|
|
|
let condition = { ...data.condition };
|
|
|
condition.code = code;
|
|
|
- let totalSize = await infoItemsModel.find(condition).count();
|
|
|
+ /*
|
|
|
+ 2021-03-31 先按编号去取,所有匹配结果再过滤,不能再分类了
|
|
|
+ let totalSize = await infoItemsModel.find(condition).count();
|
|
|
if (data.lastID) { //有最后一行说明是查询下一页
|
|
|
condition["_id"] = {$gt:mongoose.Types.ObjectId(data.lastID)};
|
|
|
}
|
|
|
let items = [];
|
|
|
if (totalSize > 0) {
|
|
|
items = await infoItemsModel.find(condition).lean().sort({"_id":1}).limit(50);
|
|
|
- }
|
|
|
+ } */
|
|
|
|
|
|
- return {totalSize,items}
|
|
|
+ //新需求 ---------
|
|
|
+ let allItems = await infoItemsModel.find(condition).lean().sort({"_id":1});
|
|
|
+ let items = [];
|
|
|
+ if(data.keyWord && allItems.length > 1){
|
|
|
+ for(let item of allItems){
|
|
|
+ if(item.name.indexOf(data.keyWord) != -1) items.push(item) //有完全匹配的,就不用编码下的返回所有数据了
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //没有完全匹配的,分词匹配关键字
|
|
|
+ if (items.length === 0){
|
|
|
+ let nameArray = nodejieba.cut(data.keyWord);
|
|
|
+ nameArray = cusSegment(nameArray,data.keyWord);
|
|
|
+ let result = getMatchPrice(allItems,nameArray);
|
|
|
+ items = result.items;
|
|
|
+ }
|
|
|
+
|
|
|
+ let totalSize = items.length;
|
|
|
+
|
|
|
+ //新需求结束 ---------
|
|
|
+
|
|
|
+ return {totalSize,items,allItems}
|
|
|
}
|
|
|
|
|
|
|
|
@@ -152,8 +187,10 @@ async function getDataByKeyWord(keyword, data) {
|
|
|
|
|
|
//按全关键字匹配
|
|
|
async function getDataByFullKeyWord(keyword, data){
|
|
|
- data.condition.name = new RegExp(keyword);
|
|
|
- let items = await infoItemsModel.find(data.condition).lean().sort({"_id":1});
|
|
|
+ let items = [];
|
|
|
+ data.condition.name = new RegExp(keyword);
|
|
|
+ items = await infoItemsModel.find(data.condition).lean().sort({"_id":1});
|
|
|
+
|
|
|
delete data.condition.name;
|
|
|
return{totalSize:items.length,items}
|
|
|
}
|
|
@@ -177,6 +214,52 @@ function handelThreeWord(word){
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+function getShortNameArray(nameArray){
|
|
|
+ let newArray = [];
|
|
|
+ for(let n of nameArray){
|
|
|
+ if(n.length >= 5){
|
|
|
+ newArray.push(...nodejieba.cutSmall(n,3))
|
|
|
+ }else{
|
|
|
+ newArray.push(n);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return newArray;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+function getMatchPrice(allInfoPrice,nameArray,needHandleLongWord = true){
|
|
|
+ let items = [];
|
|
|
+ let maxNum = 0;//最大匹配数
|
|
|
+ let matchMap = {};//匹配储存
|
|
|
+ let handleLongWord = false;
|
|
|
+ if(needHandleLongWord){
|
|
|
+ for(let na of nameArray){
|
|
|
+ if(na.length >= 5) handleLongWord = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let info of allInfoPrice) {
|
|
|
+ //specs
|
|
|
+ let mstring = info.name + info.specs;
|
|
|
+ mstring = mstring.replace(/混凝土/g, "砼");
|
|
|
+ info.mstring = mstring;
|
|
|
+ let matchCount = 0;
|
|
|
+ for (let na of nameArray) {
|
|
|
+ if (mstring.indexOf(na) != -1) {
|
|
|
+ matchCount++;
|
|
|
+ if(needHandleLongWord && na.length >= 5) handleLongWord = false//有5个字的,并且匹配上了,这里就为false不用再处理一次了
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (matchCount > 0) {
|
|
|
+ matchMap[matchCount] ? matchMap[matchCount].push(info) : matchMap[matchCount] = [info];
|
|
|
+ if (matchCount > maxNum) maxNum = matchCount;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (maxNum > 0) items = matchMap[maxNum];
|
|
|
+ totalSize = items.length
|
|
|
+ return {totalSize,items,handleLongWord};
|
|
|
+}
|
|
|
+
|
|
|
//自定义特殊处理
|
|
|
function cusSegment(nameArray,keyword){
|
|
|
let temArr = [];
|
|
@@ -201,15 +284,12 @@ function cusSegment(nameArray,keyword){
|
|
|
|
|
|
//模糊匹配
|
|
|
async function getDataByFuzzyMatch(keyword, data){
|
|
|
- let items = [];
|
|
|
+
|
|
|
let nameArray = [];
|
|
|
if (keyword.length < 3) {
|
|
|
nameArray.push(keyword)
|
|
|
} else {
|
|
|
- nameArray = segment.doSegment(keyword, {
|
|
|
- simple: true, //不返回词性
|
|
|
- stripPunctuation: true //去除标点符号
|
|
|
- });
|
|
|
+ nameArray = nodejieba.cut(keyword)
|
|
|
}
|
|
|
|
|
|
//自定义处理
|
|
@@ -217,29 +297,23 @@ async function getDataByFuzzyMatch(keyword, data){
|
|
|
|
|
|
console.log(nameArray);
|
|
|
|
|
|
- let allInfoPrice = await infoItemsModel.find(data.condition).lean().sort({"_id":1});
|
|
|
|
|
|
- let maxNum = 0;//最大匹配数
|
|
|
- let matchMap = {};//匹配储存
|
|
|
+ let allInfoPrice = await infoItemsModel.find(data.condition).lean().sort({"_id":1});
|
|
|
|
|
|
- for (let info of allInfoPrice) {
|
|
|
- //specs
|
|
|
- let mstring = info.name + info.specs;
|
|
|
- mstring = mstring.replace(/混凝土/g, "砼");
|
|
|
- info.mstring = mstring;
|
|
|
- let matchCount = 0;
|
|
|
- for (let na of nameArray) {
|
|
|
- if (mstring.indexOf(na) != -1) {
|
|
|
- matchCount++;
|
|
|
- }
|
|
|
- }
|
|
|
- if (matchCount > 0) {
|
|
|
- matchMap[matchCount] ? matchMap[matchCount].push(info) : matchMap[matchCount] = [info];
|
|
|
- if (matchCount > maxNum) maxNum = matchCount;
|
|
|
- }
|
|
|
+ let {totalSize,items,handleLongWord} = getMatchPrice(allInfoPrice,nameArray)
|
|
|
+ if(handleLongWord === true){
|
|
|
+ nameArray = getShortNameArray(nameArray);
|
|
|
+ console.log(`二次匹配:[${nameArray}]`);
|
|
|
+ let newResult = getMatchPrice(allInfoPrice,nameArray,false)
|
|
|
+ totalSize = newResult.totalSize;
|
|
|
+ items = newResult.items;
|
|
|
}
|
|
|
- if (maxNum > 0) items = matchMap[maxNum];
|
|
|
- totalSize = items.length
|
|
|
+
|
|
|
+ //关键词按权重排序,为了给结果排序
|
|
|
+ nameArray = _.sortBy(nameArray,(name)=>{
|
|
|
+ if(nameWeightMap[name]) return nameWeightMap[name]*-1;//sortBy是升序排序,我们要的是权重越小排到越后即倒序 所以这里乘以-1
|
|
|
+ return 1
|
|
|
+ })
|
|
|
|
|
|
//按匹配位置排序 如[ '橡胶', '胶圈', '给水' ] 先显示橡胶
|
|
|
items = _.sortBy(items,(item)=>{
|