首页 > 代码库 > 城市查询-拼音、全拼、简拼、混拼、卷舌音、前后鼻音、兼容查询C#与nodejs+redis应用---笔记
城市查询-拼音、全拼、简拼、混拼、卷舌音、前后鼻音、兼容查询C#与nodejs+redis应用---笔记
第一步:用C#实现拼音的全拼简拼卷舌音,前后鼻音兼容等功能。并建立redis所需查询索引等。
只是简单实现了该功能,对性能无优化。前提条件:城市拼音手动建立好。如:北京 全拼 BeiJing 区分大小写,简拼BJ 。简拼可有可无,没有的话,自己截取出来即可。
代码如下:
public class SpellIndexHelper { /// <summary> /// 声母 /// </summary> private static string[,] initialsList = new string[3, 2] { { "Z", "Zh" }, { "C", "Ch" }, { "S", "Sh" } }; /// <summary> /// 韵母 Finals /// </summary> private static string[,] finalsList = new string[5, 2] { { "an", "ang" }, { "en", "eng" }, { "in", "ing" }, { "An", "Ang" }, { "En", "Eng" } }; /// <summary> /// 声母加韵母 /// </summary> private static string[,] spellList = new string[8, 2] { { "Z", "Zh" }, { "C", "Ch" }, { "S", "Sh" }, { "an", "ang" }, { "en", "eng" }, { "in", "ing" }, { "An", "Ang" }, { "En", "Eng" } }; #region 包含函数 /// <summary> /// 中文名称匹配 /// </summary> /// <param name="value"></param> /// <param name="query"></param> /// <returns></returns> public static bool IsChineseMatch(string value, string query) { if (string.IsNullOrWhiteSpace(query) || string.IsNullOrWhiteSpace(value)) return false; if (query.Length > value.Length) return false; int len = query.Length; return value.ToLower().Substring(0, len).Contains(query.ToLower()); } /// <summary> /// 全拼匹配 /// </summary> /// <param name="value"></param> /// <param name="query"></param> /// <returns></returns> public static bool IsSpellMatch(string value, string query) { if (string.IsNullOrWhiteSpace(query) || string.IsNullOrWhiteSpace(value)) return false; string queryAppend = Append(query).ToLower(); int len = queryAppend.Length; if (len > value.Length) return false; return value.ToLower().Substring(0, len).ToLower().Contains(queryAppend); } #endregion /// <summary> /// 追加模糊匹配的全部增量(BeiJin->BeiJing) /// </summary> /// <param name="spell"></param> /// <returns></returns> public static string Append(string spell) { //for (int i = 0; i < 8; i++) //{ // spell = spell.Replace(spellList[i, 0], spellList[i, 1]); //} //spell = spell.Replace("hh", "h"); //spell = spell.Replace("gg", "g"); //return spell; return Append(spell, false); } /// <summary> /// 追加模糊匹配的全部增量并转换为小写(BeiJin->beijing) /// </summary> /// <param name="spell"></param> /// <param name="isLower"></param> /// <returns></returns> public static string Append(string spell, bool isLower) { spell = isLower ? spell.ToLower() : spell; if (spell == "shijiazhuang") { } for (int i = 0; i < 8; i++) { spell = isLower ? spell.Replace(spellList[i, 0].ToLower(), spellList[i, 1].ToLower()) : spell.Replace(spellList[i, 0], spellList[i, 1]); } spell = spell.Replace("hh", "h"); spell = spell.Replace("gg", "g"); return spell; } /// <summary> /// 追加声母 /// </summary> /// <param name="spell"></param> /// <returns></returns> public static string AppendInitials(string spell) { for (int i = 0; i < 3; i++) { spell = spell.Replace(initialsList[i, 0], initialsList[i, 1]); } spell = spell.Replace("hh", "h"); return spell; } /// <summary> /// 追加韵母 /// </summary> /// <param name="spell"></param> /// <returns></returns> public static string AppendFinals(string spell) { for (int i = 0; i < 5; i++) { spell = spell.Replace(finalsList[i, 0], finalsList[i, 1]); } spell = spell.Replace("gg", "g"); return spell; } /// <summary> /// 去掉模糊匹配全部增量(beijing->beijin) /// </summary> /// <param name="spell"></param> /// <returns></returns> public static string Remove(string spell) { for (int i = 0; i < 8; i++) { spell = spell.Replace(spellList[i, 1], spellList[i, 0]); } return spell; } /// <summary> /// 去掉模糊匹配声母 /// </summary> /// <param name="spell"></param> /// <returns></returns> public static string RemoveInitials(string spell) { for (int i = 0; i < 3; i++) { spell = spell.Replace(initialsList[i, 1], initialsList[i, 0]); } return spell; } /// <summary> /// 去掉模糊匹配韵母 /// </summary> /// <param name="spell"></param> /// <returns></returns> public static string RemoveFinals(string spell) { for (int i = 0; i < 5; i++) { spell = spell.Replace(finalsList[i, 1], finalsList[i, 0]); } return spell; } /// <summary> /// 根据大小写分割拼音(BeiJing,分割为Bei Jing) /// </summary> /// <param name="spell"></param> /// <returns></returns> public static List<string> SplitSpell(string spell) { if (string.IsNullOrWhiteSpace(spell)) { return null; } int length = spell.Length; List<string> list = new List<string>(); string splitPY = null; for (int i = 0; i < length; i++) { if (char.IsUpper(spell, i))//大写 { if (splitPY != null) list.Add(splitPY); splitPY = null;//清空 splitPY += spell.Substring(i, 1); if (i == length - 1)//如果是最后一个 { list.Add(splitPY); } } if (char.IsLower(spell, i))//小写 { splitPY += spell.Substring(i, 1); if (i == length - 1)//如果是最后一个 { list.Add(splitPY); } } } return list; } /// <summary> /// 简拼/全拼 全适配索引 /// </summary> /// <param name="oldSpell">每个元素为单个拼音 (简拼/全拼 非补全)</param> /// <param name="newSpell">每个元素为单个拼音 (简拼/全拼 补全 ) </param> /// <returns></returns> private static string GetCombination(List<string> oldSpell, List<string> newSpell) { int length = oldSpell.Count; string result = null; ; for (int i = 0; i < length; i++) { string combinationResult = null; for (int j = 0; j < length; j++) { if (i == j) { combinationResult += oldSpell[i]; } else { combinationResult += newSpell[j]; } } result += combinationResult + ";"; } return result; } /// <summary> /// 创建所有混拼索引 /// </summary> /// <param name="shortSpell"></param> /// <param name="spell"></param> /// <returns></returns> public static string CreateHybridIndex(string shortSpell, string spell) { List<List<string>> list = new List<List<string>>(); //第一层有多少个分割的拼音,第二层拼音 list.Add(SplitSpell(shortSpell)); //添加原始数据---简拼 list.Add(SplitSpell(AppendInitials(shortSpell))); //添加补全声母---简拼 list.Add(SplitSpell(spell)); //添加原始数据---全拼 list.Add(SplitSpell(AppendInitials(spell))); //添加补全声母---全拼 list.Add(SplitSpell(Append(spell))); //添加补全-------全拼 list.Add(SplitSpell(AppendFinals(spell))); //添加补全韵母---全拼 list.Add(SplitSpell(RemoveInitials(spell))); //移除所有声母---全拼 list.Add(SplitSpell(RemoveFinals(spell))); //移除所有韵母---全拼 list.Add(SplitSpell(Remove(spell))); //移除所有-------全拼 string result = null; foreach (var item1 in list) { foreach (var item2 in list) { if (item1 != item2) { result += GetCombination(item1, item2); } } } return Distinct(result); } /// <summary> /// 去重 /// </summary> /// <param name="hybridSpell"></param> /// <returns></returns> private static string Distinct(string hybridSpell) { var list = hybridSpell.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Distinct(); string result = null; foreach (var item in list) { result += item + ";"; } return result.Substring(0, result.Length - 1); } }
C#调用
<pre class="csharp" name="code"> string shortSpell = SpellIndexHelper.Append(list[i].ShorSpell.Trim());//StrCityCodeHelper.GetNewShortSpell(list[i].ShorSpell.Trim()); string spell = SpellIndexHelper.Append(list[i].Spell.Trim());//StrCityCodeHelper.GetNewSpell(list[i].Spell.Trim());
list[i].SpellIndex = SpellIndexHelper.CreateHybridIndex(list[i].ShorSpell.Trim(), list[i].Spell.Trim()); _insuranceRegionService.Updata(list[i]);
生成混拼索引后存入SQL数据库中,效果如下:
第二步:用nodejs实现查询功能。
nodejs的异步真的很操蛋啊,真是个陷阱。从redis取数据的时候真麻烦。
nodejs 代码如下:
var dbHelper = require('../../WebApi/MSSQL/dbHelper.js'); var cluster = require('cluster'); var numCPUs = require('os').cpus().length; //var idd=1; /*dbHelper.select("dbo.[InsuranceRegion]",1,"where id=@id",{id: idd},"order by id",function(err,result){ console.log(result); });*/ //dbHelper.select("dbo.InsuranceRegion","","","","order by RegionId",function(err,result){ //console.log(result); //}); var redis = require("redis"); var express = require("express"); var app=express(); var isSuccess =false; var client = redis.createClient('6379', '192.168.151.87'); // redis 链接错误 client.on("error", function(error) { console.log(error); }); var convertNullToEmptyStr=function(data){ return data==null?"":data; }; var convertToBool=function(data){ return data==null?0:1; }; /* var json = "{'name':'aa','age':18}"; var jsonobj = eval('('+json+")"); for (var key in jsonobj) { console.log(key) }*/ var sql ="SELECT [InsuranceRegion].[RegionId] ,[CityID] ,[Name] ,[Spell] ,[FullName] ,[Level] ,[OrderNumber] ,[ShorSpell] ,[HotFlag] ,[HotOrderNumber] ,[LicensePlateCode] ,[SpellAdapter] ,[YGBX] ,[CCIC] ,[AXATP] ,[PICC] ,[CPIC] ,[PAIC] ,[ZABX] FROM [Finance].[dbo].[InsuranceRegion] left join [InsuranceRegionMapping] on [InsuranceRegion].RegionId =[InsuranceRegionMapping].GBCode" dbHelper.querySql(sql,"",function(err,result){ for (var i in result){ client.hmset( "baoxian:Region:RegionId:"+result[i].RegionId, "RegionId",result[i].RegionId, "CityID", convertNullToEmptyStr(result[i].CityID), "Name", convertNullToEmptyStr(result[i].Name), "Spell",convertNullToEmptyStr(result[i].Spell), "FullName", convertNullToEmptyStr(result[i].FullName), "Level", convertNullToEmptyStr(result[i].Level), "OrderNumber", convertNullToEmptyStr(result[i].OrderNumber), "ShorSpell", convertNullToEmptyStr(result[i].ShorSpell), "HotFlag", convertNullToEmptyStr( result[i].HotFlag), "HotOrderNumber", convertNullToEmptyStr( result[i].HotOrderNumber), "LicensePlateCode", convertNullToEmptyStr( result[i].LicensePlateCode), // "ShorSpellAdapter", convertNullToEmptyStr( result[i].ShorSpellAdapter), "SpellAdapter", convertNullToEmptyStr( result[i].SpellAdapter), "YGBX",convertToBool( result[i].YGBX), "CCIC",convertToBool( result[i].CCIC), "AXATP",convertToBool( result[i].AXATP), "PICC",convertToBool( result[i].PICC), "CPIC",convertToBool( result[i].CPIC), "PAIC",convertToBool( result[i].CPIC), "ZABX",convertToBool( result[i].CPIC) ); if(result[i].Level==2){//建立城市索引 client.sadd(["baoxian:Region:Level:2", result[i].RegionId], function(err, reply) { //console.log(reply); // 1 }); createQueryIndex(result[i].Name,result[i].RegionId); createQueryIndex(result[i].FullName,result[i].RegionId); createQuerySpell(result[i].SpellAdapter,result[i].RegionId); } else if(result[i].Level==1){//建立省索引 client.sadd("baoxian:Region:Level:1",result[i].RegionId); } else if(result[i].Level==3){//建立城镇区县索引 client.sadd("baoxian:Region:County:CityID:"+result[i].RegionId.toString().substring(0,4)+"00",result[i].RegionId); } } }); /* dbHelper.select("dbo.InsuranceRegion","","","","order by RegionId",function(err,result){ //console.log(result); for (var i in result){ client.hmset( "baoxian:Region:RegionId:"+result[i].RegionId, "CityID", convertNullToEmptyStr(result[i].CityID), "Name", convertNullToEmptyStr(result[i].Name), "Spell",convertNullToEmptyStr(result[i].Spell), "FullName", convertNullToEmptyStr(result[i].FullName), "Level", convertNullToEmptyStr(result[i].Level), "OrderNumber", convertNullToEmptyStr(result[i].OrderNumber), "ShorSpell", convertNullToEmptyStr(result[i].ShorSpell), "HotFlag", convertNullToEmptyStr( result[i].HotFlag), "HotOrderNumber", convertNullToEmptyStr( result[i].HotOrderNumber), "LicensePlateCode", convertNullToEmptyStr( result[i].LicensePlateCode) ); if(result[i].Level==2){//建立城市索引 client.sadd(["baoxian:Region:Level:2", result[i].RegionId], function(err, reply) { //console.log(reply); // 1 }); createQueryIndex(result[i].Name,result[i].RegionId); createQueryIndex(result[i].Spell,result[i].RegionId); createQueryIndex(result[i].FullName,result[i].RegionId); createQueryIndex(result[i].ShorSpell,result[i].RegionId); } else if(result[i].Level==1){//建立省索引 client.sadd("baoxian:Region:Level:1",result[i].RegionId); } else if(result[i].Level==3){//建立城镇区县索引 client.sadd("baoxian:Region:County:CityID:"+result[i].RegionId.toString().substring(0,4)+"00",result[i].RegionId); } } }); */ var createQuerySpell=function(data,regionId){ console.log(data); var arry = data.split(";") ; for(var i in arry){ if(arry[i]!="") { createQueryIndex(arry[i],regionId); } } } //建立查询索引 var createQueryIndex=function(data,regionId){ var len = data.length; for(var i=1;i<=len;i++){ client.sadd(["baoxian:Region:Query:"+ data.toLowerCase().substring(0,i),regionId], function(err, reply) { //console.log(reply); // 1 }); } }; //建立移动站热点城市查询 var createMHotCityIndex=function(){ var mHotCityIndex=new Array(110100,310100,440100,440300,320100,320500,330100,370100,370200,420100,430100,210100,510100,500100,610100,340100,350100,220100,130100,410100,120100,210200); for (var i in mHotCityIndex){ client.sadd(["baoxian:Region:MHotCity",mHotCityIndex[i]], function(err, reply) { //console.log(reply); // 1 }); // client.zadd("baoxian:Region:HotCity",result[i].HotOrderNumber,result[i].RegionId); } }; createMHotCityIndex(); dbHelper.select("dbo.InsuranceRegion","","where Level=2 and HotFlag=1 ","","order by [HotOrderNumber]",function(err,result){ //console.log(result); for (var i in result){ client.sadd(["baoxian:Region:HotCity",result[i].RegionId], function(err, reply) { //console.log(reply); // 1 }); // client.zadd("baoxian:Region:HotCity",result[i].HotOrderNumber,result[i].RegionId); } }); if (cluster.isMaster) { // Fork workers. fock num of CPUS - 1 works for (var i = 1; i <= numCPUs; i++) { cluster.fork(); } cluster.on('exit', function(worker, code, signal) { console.log('worker ' + worker.process.pid + ' died'); }); cluster.on('fork', function(worker, code, signal) { console.log('worker ' + worker.process.pid + ' is online'); }); } else { app.get('/CityQuery', function(req, res) { res.writeHead(200, { "Content-Type": "text/plain;charset=utf-8" }); var data={ Result:true, Message:null, Data:null }; try { var key = req.query.key; console.log(key); var jsonp = req.query.jsoncallback; key=decodeURIComponent(key).toLowerCase(); if(key==""|| key == null || key == undefined){ data.Result=false; data.Message ="查询参数为空!"; res.end(jsonp+"("+JSON.stringify(data)+")"); } else{ client.smembers('baoxian:Region:Query:'+key, function(err, reply) { var len = reply.length console.log(len); console.log(reply); if(len==0) { //data.Result=t; data.Message ="没有匹配项!"; return res.end(jsonp + "(" + JSON.stringify(data) + ")"); } var queryResult=new Array([len]); var j=0; for(var i=0 ;i<len;i++) { client.hgetall("baoxian:Region:RegionId:" + reply[i], function (err, replyData) { queryResult[j]=replyData; j++; if(queryResult[len-1]!=undefined){ data.Data = queryResult; res.end(jsonp+"("+JSON.stringify(data)+")"); } }); } }); } } catch (error){ console.log("[error]:"+error.name+error.message); res.end(error.name+error.message); } //WriteLogs(isSuccess,res); //res.end("数据提交完毕!"); //console.log(req.query.key); }); app.get('/HotCity', function(req, res) { var data={ Result:true, Message:null, Data:null }; try { var jsonp =req.query.jsoncallback; console.log(jsonp); client.smembers('baoxian:Region:HotCity', function(err, reply) { var len = reply.length; var queryResult=new Array([len]); var j=0; for(var i=0 ;i<len;i++) { client.hgetall("baoxian:Region:RegionId:" + reply[i], function (err, replyData) { queryResult[j]=replyData; j++; if(queryResult[len-1]!=undefined){ data.Data = queryResult; //console.log(jsonp+JSON.stringify(queryResult)); res.end(jsonp+"("+JSON.stringify(data)+")"); } }); } }); } catch (error){ console.log("[error]:"+error.name+error.message); res.end(error.name+error.message); } res.writeHead(200, { "Content-Type": "text/plain;charset=utf-8" }); //WriteLo }); app.get('/HotMCity', function(req, res) { }); app.listen(9800); }
nodejs查询效果如下:
城市查询-拼音、全拼、简拼、混拼、卷舌音、前后鼻音、兼容查询C#与nodejs+redis应用---笔记
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。