This commit is contained in:
Your Name 2021-11-20 01:03:55 +08:00
parent 2bc1109af8
commit 47e1f40355
137 changed files with 22053 additions and 0 deletions

View File

@ -0,0 +1,18 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
#-*- coding: utf-8 -*-
from ExcelReader import convertFile
from ExcelReader import generateOutputPaths
from ExcelReader import generateSimilarWordMap
if __name__ == "__main__":
targetPath = "..\\..\\COVID19"
vJsonPath, eJsonPath, intentPath, entityMapPath, colorJsonPath = generateOutputPaths(targetPath, "COVID19")
excelPath ="..\\excel\\COVID19\\SmartKG_KGDesc_COVID19_zh.xlsx"
similarWordMap = generateSimilarWordMap("..\\excel\\COVID19\\similarWords_COVID19_zn.tsv")
convertFile(excelPath, [], ["COVID19"], similarWordMap, vJsonPath, eJsonPath, intentPath, entityMapPath, True, colorJsonPath)

View File

@ -0,0 +1,15 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
from ExcelReader import convertFile
from ExcelReader import generateOutputPaths
if __name__ == "__main__":
targetPath = "..\\..\\COVID19_en"
vJsonPath, eJsonPath, intentPath, entityMapPath, colorJsonPath = generateOutputPaths(targetPath, "COVID19_en")
excelPath = "..\\excel\\COVID19\\SmartKG_KGDesc_COVID19_en.xlsx"
convertFile(excelPath, [], ["COVID19_en"], [], vJsonPath, eJsonPath, intentPath, entityMapPath, True, colorJsonPath)

View File

@ -0,0 +1,20 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
#-*- coding: utf-8 -*-
from ExcelReader import convertFile
from ExcelReader import generateOutputPaths
default_rules = ["PhonicsGrade7\tPOSITIVE\t声|音调|传播", "MechanicsGrade7\tPOSITIVE\t力|运动|向量"]
if __name__ == "__main__":
targetPath = "..\\..\\Physics"
vJsonPath, eJsonPath, intentPath, entityMapPath, colorJsonPath = generateOutputPaths(targetPath, "PhonicsGrade7")
excelPath = "..\\excel\\Physics\\SmartKG_KGDesc_PhonicsGrade7_zh.xlsx"
convertFile(excelPath, [], ["PhonicsGrade7"], [], vJsonPath, eJsonPath, intentPath, entityMapPath, colorJsonPath)
vJsonPath, eJsonPath, intentPath, entityMapPath, colorJsonPath = generateOutputPaths(targetPath, "MechanicsGrade7")
excelPath = "..\\excel\\Physics\\SmartKG_KGDesc_MechanicsGrade7_zh.xlsx"
convertFile(excelPath, [], ["MechanicsGrade7"], [], vJsonPath, eJsonPath, intentPath, entityMapPath, colorJsonPath)

View File

@ -0,0 +1,24 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
#-*- coding: utf-8 -*-
from ExcelReader import convertFile
from ExcelReader import generateOutputPaths
default_rules = []
if __name__ == "__main__":
targetPath = "..\\..\\Physics2"
scenario = "MotionAndPower"
vJsonPath, eJsonPath, intentPath, entityMapPath, colorJsonPath = generateOutputPaths(targetPath, scenario, True)
excelPath = "..\\excel\\Physics2\\SmartKG_KGDesc_MotionAndPower_zh.xlsx"
convertFile(excelPath, [], [scenario], [], vJsonPath, eJsonPath, intentPath, entityMapPath, colorJsonPath)
scenario = "Phonics"
vJsonPath, eJsonPath, intentPath, entityMapPath, colorJsonPath = generateOutputPaths(targetPath, scenario, False)
excelPath = "..\\excel\\Physics\\SmartKG_KGDesc_PhonicsGrade7_zh.xlsx"
convertFile(excelPath, [], [scenario], [], vJsonPath, eJsonPath, intentPath, entityMapPath, colorJsonPath)

View File

@ -0,0 +1,178 @@
[
{
"headVertexId": "entity_gainian1_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian2_MotionAndPower"
},
{
"headVertexId": "entity_gainian1_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian3_MotionAndPower"
},
{
"headVertexId": "entity_gainian1_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian7_MotionAndPower"
},
{
"headVertexId": "entity_gainian3_MotionAndPower",
"relationType": "测量工具为",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian4_MotionAndPower"
},
{
"headVertexId": "entity_gainian5_MotionAndPower",
"relationType": "产生",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian3_MotionAndPower"
},
{
"headVertexId": "entity_gainian3_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian6_MotionAndPower"
},
{
"headVertexId": "entity_gainian8_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian9_MotionAndPower"
},
{
"headVertexId": "entity_gainian8_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian13_MotionAndPower"
},
{
"headVertexId": "entity_gainian9_MotionAndPower",
"relationType": "相关物理量有",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian10_MotionAndPower"
},
{
"headVertexId": "entity_gainian9_MotionAndPower",
"relationType": "相关物理量有",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian11_MotionAndPower"
},
{
"headVertexId": "entity_gainian8_MotionAndPower",
"relationType": "判断标准",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian12_MotionAndPower"
},
{
"headVertexId": "entity_gainian13_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian14_MotionAndPower"
},
{
"headVertexId": "entity_gainian14_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian15_MotionAndPower"
},
{
"headVertexId": "entity_gainian14_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian16_MotionAndPower"
},
{
"headVertexId": "entity_gainian15_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian17_MotionAndPower"
},
{
"headVertexId": "entity_gainian15_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian18_MotionAndPower"
},
{
"headVertexId": "entity_gainian1_MotionAndPower",
"relationType": "属于",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian19_MotionAndPower"
},
{
"headVertexId": "entity_gainian8_MotionAndPower",
"relationType": "属于",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian19_MotionAndPower"
},
{
"headVertexId": "entity_gainian19_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian20_MotionAndPower"
},
{
"headVertexId": "entity_gainian20_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian21_MotionAndPower"
},
{
"headVertexId": "entity_gainian19_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian22_MotionAndPower"
},
{
"headVertexId": "entity_gainian19_MotionAndPower",
"relationType": "包含",
"scenarios": [
"MotionAndPower"
],
"tailVertexId": "entity_gainian23_MotionAndPower"
}
]

View File

@ -0,0 +1,98 @@
[
{
"headVertexId": "entity_gainian1_Phonics",
"relationType": "包含",
"scenarios": [
"Phonics"
],
"tailVertexId": "entity_gainian2_Phonics"
},
{
"headVertexId": "entity_gainian1_Phonics",
"relationType": "包含",
"scenarios": [
"Phonics"
],
"tailVertexId": "entity_gainian3_Phonics"
},
{
"headVertexId": "entity_gainian1_Phonics",
"relationType": "包含",
"scenarios": [
"Phonics"
],
"tailVertexId": "entity_gainian4_Phonics"
},
{
"headVertexId": "entity_gainian1_Phonics",
"relationType": "包含",
"scenarios": [
"Phonics"
],
"tailVertexId": "entity_gainian8_Phonics"
},
{
"headVertexId": "entity_gainian1_Phonics",
"relationType": "包含",
"scenarios": [
"Phonics"
],
"tailVertexId": "entity_gainian11_Phonics"
},
{
"headVertexId": "entity_gainian4_Phonics",
"relationType": "包含",
"scenarios": [
"Phonics"
],
"tailVertexId": "entity_gainian5_Phonics"
},
{
"headVertexId": "entity_gainian4_Phonics",
"relationType": "包含",
"scenarios": [
"Phonics"
],
"tailVertexId": "entity_gainian6_Phonics"
},
{
"headVertexId": "entity_gainian4_Phonics",
"relationType": "包含",
"scenarios": [
"Phonics"
],
"tailVertexId": "entity_gainian7_Phonics"
},
{
"headVertexId": "entity_gainian8_Phonics",
"relationType": "包含",
"scenarios": [
"Phonics"
],
"tailVertexId": "entity_gainian9_Phonics"
},
{
"headVertexId": "entity_gainian8_Phonics",
"relationType": "包含",
"scenarios": [
"Phonics"
],
"tailVertexId": "entity_gainian10_Phonics"
},
{
"headVertexId": "entity_gainian11_Phonics",
"relationType": "包含",
"scenarios": [
"Phonics"
],
"tailVertexId": "entity_gainian12_Phonics"
},
{
"headVertexId": "entity_gainian11_Phonics",
"relationType": "包含",
"scenarios": [
"Phonics"
],
"tailVertexId": "entity_gainian13_Phonics"
}
]

View File

@ -0,0 +1,444 @@
[
{
"id": "entity_gainian1_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "力",
"nodeType": "ROOT",
"properties": [
{
"name": "含义",
"value": "物体对物体的作用"
},
{
"name": "作用效果",
"value": "改变物体运动状态;改变物体形状"
},
{
"name": "三要素",
"value": "大小、方向、作用点"
},
{
"name": "特点",
"value": "力的作用是相互的"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian2_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "重力",
"nodeType": "LEAF",
"properties": [
{
"name": "含义",
"value": "由于地球的吸引而使物体受到的力"
},
{
"name": "公式",
"value": "G=mg"
},
{
"name": "方向",
"value": "竖直向下"
},
{
"name": "作用点",
"value": "重心(悬挂法)"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian3_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "弹力",
"nodeType": "MIDDLE",
"properties": [
{
"name": "含义",
"value": "物体由于发生弹性形变而产生的力"
},
{
"name": "产生条件",
"value": "1.物体相互接触2.物体具有弹性,且发生弹性形变"
},
{
"name": "包括",
"value": "弹簧伸长与压缩时的力,压力、支持力、绳子拉力等"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian4_MotionAndPower",
"label": "物体",
"leadSentence": "",
"name": "弹簧测力计",
"nodeType": "LEAF",
"properties": [
{
"name": "原理",
"value": "在弹性限度内,弹簧的伸长量与受到的拉力成正比"
},
{
"name": "构造",
"value": "弹簧、刻度盘、指针、挂钩、吊环"
},
{
"name": "使用",
"value": "量程、分度值"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian5_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "弹性形变",
"nodeType": "ROOT",
"properties": [
{
"name": "含义",
"value": "对弹性物体来说,形变后能自动恢复原状的最大限度叫弹性限度;物体在弹性限度内发生的形变叫做弹性形变"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian6_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "弹簧伸长与压缩时的力,压力、支持力、绳子拉力等",
"nodeType": "LEAF",
"properties": [],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian7_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "摩擦力",
"nodeType": "LEAF",
"properties": [
{
"name": "含义",
"value": "两个相互接触的物体,当它们相对滑动或有相对运动趋势时,在接触面上会产生一种阻碍相对运动或相对运动趋势的力,这种力叫做滑动摩擦力"
},
{
"name": "产生条件",
"value": "1.接触面粗糙 2.想物体相互接触并相互挤压 3.两物体间发生相对运动或有相对运动趋势"
},
{
"name": "分类",
"value": "静摩擦力、滑动摩擦力"
},
{
"name": "影响滑动摩擦力因素",
"value": "压力大小、接触面的粗糙程度"
},
{
"name": "作用效果",
"value": "阻碍物体的相对运动或相对运动趋势"
},
{
"name": "作用点",
"value": "在接触面上"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian8_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "机械运动",
"nodeType": "ROOT",
"properties": [
{
"name": "含义",
"value": " 一个物体相对于另一个物体的位置,或者一个物体的某些部分相对于其他部分的位置,随着时间而变化的过程叫做机械运动"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian9_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "描述运动位置",
"nodeType": "MIDDLE",
"properties": [],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian10_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "长度",
"nodeType": "LEAF",
"properties": [
{
"name": "单位",
"value": "国际单位米m"
},
{
"name": "测量工具",
"value": "刻度尺,估读到准确值的下一位"
},
{
"name": "估测",
"value": "选取标准进行对比"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian11_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "时间",
"nodeType": "LEAF",
"properties": [
{
"name": "单位",
"value": "国际单位s"
},
{
"name": "测量工具",
"value": "停表"
},
{
"name": "估测",
"value": "选取标准进行对比"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian12_MotionAndPower",
"label": "物体",
"leadSentence": "",
"name": "参照物",
"nodeType": "LEAF",
"properties": [
{
"name": "含义",
"value": "判断物体运动还是静止时,作为标准的物体"
},
{
"name": "选择原则",
"value": "不以研究对象本身为参照物"
},
{
"name": "相对性",
"value": "运动和静止的相对性"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian13_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "描述运动快慢",
"nodeType": "MIDDLE",
"properties": [
{
"name": "三种比较方法",
"value": "1.时间相同比路程 2路程相同比时间 3.时间路程均不相同比较路程与时间的比值"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian14_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "速度",
"nodeType": "MIDDLE",
"properties": [
{
"name": "含义",
"value": "路程与时间的比值"
},
{
"name": "公式",
"value": "v=s/t"
},
{
"name": "单位",
"value": "m/s"
},
{
"name": "物理意义",
"value": "描述物体运动快慢的物理量"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian15_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "直线运动",
"nodeType": "MIDDLE",
"properties": [],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian16_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "曲线运动",
"nodeType": "LEAF",
"properties": [],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian17_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "匀速直线运动",
"nodeType": "LEAF",
"properties": [],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian18_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "变速直线运动",
"nodeType": "LEAF",
"properties": [],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian19_MotionAndPower",
"label": "关联",
"leadSentence": "",
"name": "运动和力",
"nodeType": "MIDDLE",
"properties": [
{
"name": "关系",
"value": "静止或匀速直线运动时不受力或者二力平衡;变速运动时,受非平衡力"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian20_MotionAndPower",
"label": "规律",
"leadSentence": "",
"name": "牛顿第一定律",
"nodeType": "MIDDLE",
"properties": [
{
"name": "含义",
"value": "一切物体在没受到力的作用时,总保持静止状态或匀速直线运动状态"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian21_MotionAndPower",
"label": "概念",
"leadSentence": "",
"name": "惯性",
"nodeType": "LEAF",
"properties": [
{
"name": "含义",
"value": "一切物体都有保持原来运动状态不变的性质,这种性质叫做惯性"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian22_MotionAndPower",
"label": "规律",
"leadSentence": "",
"name": "二力平衡",
"nodeType": "LEAF",
"properties": [
{
"name": "含义",
"value": "物体受到几个力的作用时,如果保持静止或者匀速直线运动状态,则这几个力相互平衡。"
},
{
"name": "条件",
"value": "同体、等大、反向、共线"
}
],
"scenarios": [
"MotionAndPower"
]
},
{
"id": "entity_gainian23_MotionAndPower",
"label": "规律",
"leadSentence": "",
"name": "同一直线上二力的合成",
"nodeType": "LEAF",
"properties": [
{
"name": "大小",
"value": "二力同向,合力为两个力的和;二力反向,合力为两个力的差的绝对值"
},
{
"name": "方向",
"value": "二力同向,方向不变;二力反向,方向与较大力的方向一致"
}
],
"scenarios": [
"MotionAndPower"
]
}
]

View File

@ -0,0 +1,234 @@
[
{
"id": "entity_gainian1_Phonics",
"label": "概念",
"leadSentence": "相关的概念有下面这些,请输入对应选项查看详情",
"name": "声现象",
"nodeType": "ROOT",
"properties": [],
"scenarios": [
"Phonics"
]
},
{
"id": "entity_gainian2_Phonics",
"label": "行为",
"leadSentence": "",
"name": "产生",
"nodeType": "LEAF",
"properties": [
{
"name": "原因",
"value": "声源的振动"
}
],
"scenarios": [
"Phonics"
]
},
{
"id": "entity_gainian3_Phonics",
"label": "行为",
"leadSentence": "",
"name": "传播",
"nodeType": "LEAF",
"properties": [
{
"name": "条件",
"value": "需要介质"
},
{
"name": "形式",
"value": "声波"
},
{
"name": "速度",
"value": "v固v液v气15℃空气中传播速度为340m/s"
}
],
"scenarios": [
"Phonics"
]
},
{
"id": "entity_gainian4_Phonics",
"label": "属性",
"leadSentence": "相关的概念有下面这些,请输入对应选项查看详情",
"name": "特性",
"nodeType": "MIDDLE",
"properties": [],
"scenarios": [
"Phonics"
]
},
{
"id": "entity_gainian5_Phonics",
"label": "概念",
"leadSentence": "",
"name": "音调",
"nodeType": "LEAF",
"properties": [
{
"name": "含义",
"value": "表示声音的高低"
},
{
"name": "影响因素",
"value": "发生物体振动的频率"
},
{
"name": "分类",
"value": "超声波、声音、次声波"
}
],
"scenarios": [
"Phonics"
]
},
{
"id": "entity_gainian6_Phonics",
"label": "概念",
"leadSentence": "",
"name": "响度",
"nodeType": "LEAF",
"properties": [
{
"name": "含义",
"value": "人耳感受到的声音强弱"
},
{
"name": "影响因素",
"value": "发声体的振幅、距离发声体的远近"
}
],
"scenarios": [
"Phonics"
]
},
{
"id": "entity_gainian7_Phonics",
"label": "概念",
"leadSentence": "",
"name": "音色",
"nodeType": "LEAF",
"properties": [
{
"name": "含义",
"value": "每个物体发出的声音特有的品质"
},
{
"name": "影响因素",
"value": "发声体材料、结构、振动方式"
}
],
"scenarios": [
"Phonics"
]
},
{
"id": "entity_gainian8_Phonics",
"label": "行为",
"leadSentence": "相关的概念有下面这些,请输入对应选项查看详情",
"name": "声的利用",
"nodeType": "MIDDLE",
"properties": [],
"scenarios": [
"Phonics"
]
},
{
"id": "entity_gainian9_Phonics",
"label": "行为",
"leadSentence": "",
"name": "传递信息",
"nodeType": "LEAF",
"properties": [
{
"name": "内容",
"value": "回声定位、声呐、B超等"
}
],
"scenarios": [
"Phonics"
]
},
{
"id": "entity_gainian10_Phonics",
"label": "行为",
"leadSentence": "",
"name": "传递能量",
"nodeType": "LEAF",
"properties": [
{
"name": "内容",
"value": "超声波碎石、超声波清洗机器等"
}
],
"scenarios": [
"Phonics"
]
},
{
"id": "entity_gainian11_Phonics",
"label": "属性",
"leadSentence": "相关的概念有下面这些,请输入对应选项查看详情",
"name": "类别",
"nodeType": "MIDDLE",
"properties": [],
"scenarios": [
"Phonics"
]
},
{
"id": "entity_gainian12_Phonics",
"label": "概念",
"leadSentence": "",
"name": "乐音",
"nodeType": "LEAF",
"properties": [
{
"name": "物理角度定义",
"value": "指发生物体有规律振动产生的声音"
},
{
"name": "环境角度定义",
"value": "指悦耳动听、令人愉悦的声音"
}
],
"scenarios": [
"Phonics"
]
},
{
"id": "entity_gainian13_Phonics",
"label": "概念",
"leadSentence": "",
"name": "噪声",
"nodeType": "LEAF",
"properties": [
{
"name": "物理角度定义",
"value": "发声体做无规则的振动时发出的声音"
},
{
"name": "环境角度定义",
"value": "凡是妨碍人正常休息,学习和工作的声音,以及对人民要听的声音起干扰作用的声音都属于噪声"
},
{
"name": "等级",
"value": "用分贝表示dB"
},
{
"name": "危害",
"value": "影响注意力甚至是身体健康"
},
{
"name": "噪声控制途径",
"value": "1.声源处减弱 2.传播过程中减弱 3.人耳出减弱"
}
],
"scenarios": [
"Phonics"
]
}
]

View File

@ -0,0 +1,53 @@
MotionAndPower 力 力 NodeName
MotionAndPower 速度 速度 NodeName
MotionAndPower 重力 重力 NodeName
MotionAndPower 匀速直线运动 匀速直线运动 NodeName
MotionAndPower 时间 时间 NodeName
MotionAndPower 摩擦力 摩擦力 NodeName
MotionAndPower 弹力 弹力 NodeName
MotionAndPower 曲线运动 曲线运动 NodeName
MotionAndPower 惯性 惯性 NodeName
MotionAndPower 弹簧伸长与压缩时的力,压力、支持力、绳子拉力等 弹簧伸长与压缩时的力,压力、支持力、绳子拉力等 NodeName
MotionAndPower 机械运动 机械运动 NodeName
MotionAndPower 描述运动位置 描述运动位置 NodeName
MotionAndPower 二力平衡 二力平衡 NodeName
MotionAndPower 直线运动 直线运动 NodeName
MotionAndPower 同一直线上二力的合成 同一直线上二力的合成 NodeName
MotionAndPower 弹簧测力计 弹簧测力计 NodeName
MotionAndPower 弹性形变 弹性形变 NodeName
MotionAndPower 描述运动快慢 描述运动快慢 NodeName
MotionAndPower 运动和力 运动和力 NodeName
MotionAndPower 参照物 参照物 NodeName
MotionAndPower 牛顿第一定律 牛顿第一定律 NodeName
MotionAndPower 长度 长度 NodeName
MotionAndPower 变速直线运动 变速直线运动 NodeName
MotionAndPower 构造 构造 PropertyName
MotionAndPower 测量工具 测量工具 PropertyName
MotionAndPower 使用 使用 PropertyName
MotionAndPower 作用效果 作用效果 PropertyName
MotionAndPower 方向 方向 PropertyName
MotionAndPower 特点 特点 PropertyName
MotionAndPower 作用点 作用点 PropertyName
MotionAndPower 原理 原理 PropertyName
MotionAndPower 条件 条件 PropertyName
MotionAndPower 关系 关系 PropertyName
MotionAndPower 单位 单位 PropertyName
MotionAndPower 物理意义 物理意义 PropertyName
MotionAndPower 产生条件 产生条件 PropertyName
MotionAndPower 相对性 相对性 PropertyName
MotionAndPower 选择原则 选择原则 PropertyName
MotionAndPower 含义 含义 PropertyName
MotionAndPower 影响滑动摩擦力因素 影响滑动摩擦力因素 PropertyName
MotionAndPower 大小 大小 PropertyName
MotionAndPower 估测 估测 PropertyName
MotionAndPower 分类 分类 PropertyName
MotionAndPower 包括 包括 PropertyName
MotionAndPower 公式 公式 PropertyName
MotionAndPower 三种比较方法 三种比较方法 PropertyName
MotionAndPower 三要素 三要素 PropertyName
MotionAndPower 产生 产生 RelationType
MotionAndPower 属于 属于 RelationType
MotionAndPower 相关物理量有 相关物理量有 RelationType
MotionAndPower 判断标准 判断标准 RelationType
MotionAndPower 测量工具为 测量工具为 RelationType
MotionAndPower 包含 包含 RelationType
1 MotionAndPower NodeName
2 MotionAndPower 速度 速度 NodeName
3 MotionAndPower 重力 重力 NodeName
4 MotionAndPower 匀速直线运动 匀速直线运动 NodeName
5 MotionAndPower 时间 时间 NodeName
6 MotionAndPower 摩擦力 摩擦力 NodeName
7 MotionAndPower 弹力 弹力 NodeName
8 MotionAndPower 曲线运动 曲线运动 NodeName
9 MotionAndPower 惯性 惯性 NodeName
10 MotionAndPower 弹簧伸长与压缩时的力,压力、支持力、绳子拉力等 弹簧伸长与压缩时的力,压力、支持力、绳子拉力等 NodeName
11 MotionAndPower 机械运动 机械运动 NodeName
12 MotionAndPower 描述运动位置 描述运动位置 NodeName
13 MotionAndPower 二力平衡 二力平衡 NodeName
14 MotionAndPower 直线运动 直线运动 NodeName
15 MotionAndPower 同一直线上二力的合成 同一直线上二力的合成 NodeName
16 MotionAndPower 弹簧测力计 弹簧测力计 NodeName
17 MotionAndPower 弹性形变 弹性形变 NodeName
18 MotionAndPower 描述运动快慢 描述运动快慢 NodeName
19 MotionAndPower 运动和力 运动和力 NodeName
20 MotionAndPower 参照物 参照物 NodeName
21 MotionAndPower 牛顿第一定律 牛顿第一定律 NodeName
22 MotionAndPower 长度 长度 NodeName
23 MotionAndPower 变速直线运动 变速直线运动 NodeName
24 MotionAndPower 构造 构造 PropertyName
25 MotionAndPower 测量工具 测量工具 PropertyName
26 MotionAndPower 使用 使用 PropertyName
27 MotionAndPower 作用效果 作用效果 PropertyName
28 MotionAndPower 方向 方向 PropertyName
29 MotionAndPower 特点 特点 PropertyName
30 MotionAndPower 作用点 作用点 PropertyName
31 MotionAndPower 原理 原理 PropertyName
32 MotionAndPower 条件 条件 PropertyName
33 MotionAndPower 关系 关系 PropertyName
34 MotionAndPower 单位 单位 PropertyName
35 MotionAndPower 物理意义 物理意义 PropertyName
36 MotionAndPower 产生条件 产生条件 PropertyName
37 MotionAndPower 相对性 相对性 PropertyName
38 MotionAndPower 选择原则 选择原则 PropertyName
39 MotionAndPower 含义 含义 PropertyName
40 MotionAndPower 影响滑动摩擦力因素 影响滑动摩擦力因素 PropertyName
41 MotionAndPower 大小 大小 PropertyName
42 MotionAndPower 估测 估测 PropertyName
43 MotionAndPower 分类 分类 PropertyName
44 MotionAndPower 包括 包括 PropertyName
45 MotionAndPower 公式 公式 PropertyName
46 MotionAndPower 三种比较方法 三种比较方法 PropertyName
47 MotionAndPower 三要素 三要素 PropertyName
48 MotionAndPower 产生 产生 RelationType
49 MotionAndPower 属于 属于 RelationType
50 MotionAndPower 相关物理量有 相关物理量有 RelationType
51 MotionAndPower 判断标准 判断标准 RelationType
52 MotionAndPower 测量工具为 测量工具为 RelationType
53 MotionAndPower 包含 包含 RelationType

View File

@ -0,0 +1,27 @@
Phonics 音调 音调 NodeName
Phonics 音色 音色 NodeName
Phonics 传递信息 传递信息 NodeName
Phonics 产生 产生 NodeName
Phonics 传递能量 传递能量 NodeName
Phonics 乐音 乐音 NodeName
Phonics 噪声 噪声 NodeName
Phonics 类别 类别 NodeName
Phonics 声的利用 声的利用 NodeName
Phonics 传播 传播 NodeName
Phonics 声现象 声现象 NodeName
Phonics 特性 特性 NodeName
Phonics 响度 响度 NodeName
Phonics 影响因素 影响因素 PropertyName
Phonics 条件 条件 PropertyName
Phonics 危害 危害 PropertyName
Phonics 噪声控制途径 噪声控制途径 PropertyName
Phonics 速度 速度 PropertyName
Phonics 原因 原因 PropertyName
Phonics 内容 内容 PropertyName
Phonics 物理角度定义 物理角度定义 PropertyName
Phonics 等级 等级 PropertyName
Phonics 分类 分类 PropertyName
Phonics 环境角度定义 环境角度定义 PropertyName
Phonics 形式 形式 PropertyName
Phonics 含义 含义 PropertyName
Phonics 包含 包含 RelationType
1 Phonics 音调 音调 NodeName
2 Phonics 音色 音色 NodeName
3 Phonics 传递信息 传递信息 NodeName
4 Phonics 产生 产生 NodeName
5 Phonics 传递能量 传递能量 NodeName
6 Phonics 乐音 乐音 NodeName
7 Phonics 噪声 噪声 NodeName
8 Phonics 类别 类别 NodeName
9 Phonics 声的利用 声的利用 NodeName
10 Phonics 传播 传播 NodeName
11 Phonics 声现象 声现象 NodeName
12 Phonics 特性 特性 NodeName
13 Phonics 响度 响度 NodeName
14 Phonics 影响因素 影响因素 PropertyName
15 Phonics 条件 条件 PropertyName
16 Phonics 危害 危害 PropertyName
17 Phonics 噪声控制途径 噪声控制途径 PropertyName
18 Phonics 速度 速度 PropertyName
19 Phonics 原因 原因 PropertyName
20 Phonics 内容 内容 PropertyName
21 Phonics 物理角度定义 物理角度定义 PropertyName
22 Phonics 等级 等级 PropertyName
23 Phonics 分类 分类 PropertyName
24 Phonics 环境角度定义 环境角度定义 PropertyName
25 Phonics 形式 形式 PropertyName
26 Phonics 含义 含义 PropertyName
27 Phonics 包含 包含 RelationType

View File

@ -0,0 +1 @@
MotionAndPower POSITIVE 力|速度|重力|匀速直线运动|时间|摩擦力|弹力|曲线运动|惯性|弹簧伸长与压缩时的力,压力、支持力、绳子拉力等|机械运动|描述运动位置|二力平衡|直线运动|同一直线上二力的合成|弹簧测力计|弹性形变|描述运动快慢|运动和力|参照物|牛顿第一定律|长度|变速直线运动
1 MotionAndPower POSITIVE 力|速度|重力|匀速直线运动|时间|摩擦力|弹力|曲线运动|惯性|弹簧伸长与压缩时的力,压力、支持力、绳子拉力等|机械运动|描述运动位置|二力平衡|直线运动|同一直线上二力的合成|弹簧测力计|弹性形变|描述运动快慢|运动和力|参照物|牛顿第一定律|长度|变速直线运动

View File

@ -0,0 +1 @@
Phonics POSITIVE 音调|音色|传递信息|产生|传递能量|乐音|噪声|类别|声的利用|传播|声现象|特性|响度
1 Phonics POSITIVE 音调|音色|传递信息|产生|传递能量|乐音|噪声|类别|声的利用|传播|声现象|特性|响度

View File

@ -0,0 +1,49 @@
[
{
"labelsOfVertexes": [
{
"color": "#E83344",
"itemLabel": "物体"
},
{
"color": "#F5A100",
"itemLabel": "关联"
},
{
"color": "#9DE7B7",
"itemLabel": "概念"
},
{
"color": "#009DDC",
"itemLabel": "规律"
}
],
"relationTypesOfEdges": [
{
"color": "#E83344",
"itemLabel": "产生"
},
{
"color": "#F5A100",
"itemLabel": "属于"
},
{
"color": "#9DE7B7",
"itemLabel": "相关物理量有"
},
{
"color": "#009DDC",
"itemLabel": "判断标准"
},
{
"color": "#FD9F7F",
"itemLabel": "测量工具为"
},
{
"color": "#025CEA",
"itemLabel": "包含"
}
],
"scenario": "MotionAndPower"
}
]

View File

@ -0,0 +1,25 @@
[
{
"labelsOfVertexes": [
{
"color": "#E83344",
"itemLabel": "行为"
},
{
"color": "#F5A100",
"itemLabel": "概念"
},
{
"color": "#9DE7B7",
"itemLabel": "属性"
}
],
"relationTypesOfEdges": [
{
"color": "#E83344",
"itemLabel": "包含"
}
],
"scenario": "Phonics"
}
]

View File

@ -0,0 +1,18 @@
red #E83344
lightred #FD9F7F
pink #FF4C94
orange #F5A100
yellow #E5E516
lightyellow #FFFF70
green #00D86C
lightgreen #9DE7B7
icegreen #7FFFBF
blue #009DDC
iceblue #7BCDFF
bluepurple #025CEA
purple #9257ae
lightpurple #78A7FF
icepurple #D89ADA
lightgrey #EAEAEA
lightblack #333333
grey #808080
1 red #E83344
2 lightred #FD9F7F
3 pink #FF4C94
4 orange #F5A100
5 yellow #E5E516
6 lightyellow #FFFF70
7 green #00D86C
8 lightgreen #9DE7B7
9 icegreen #7FFFBF
10 blue #009DDC
11 iceblue #7BCDFF
12 bluepurple #025CEA
13 purple #9257ae
14 lightpurple #78A7FF
15 icepurple #D89ADA
16 lightgrey #EAEAEA
17 lightblack #333333
18 grey #808080

View File

@ -0,0 +1,20 @@
和尚 grey
妖怪 red
妖怪_活 pink
妖怪_死 red
神仙 blue
神仙_佛派 lightgreen
神仙_道派 blue
凡人 yellow
团体 orange
团体_妖怪 orange
上下级 blue
父子 blue
父女 blue
母子 blue
母女 blue
兄弟 lightblue
夫妻 green
兄弟 green
亲戚 lightgreen
组成 lightred
1 和尚 grey
2 妖怪 red
3 妖怪_活 pink
4 妖怪_死 red
5 神仙 blue
6 神仙_佛派 lightgreen
7 神仙_道派 blue
8 凡人 yellow
9 团体 orange
10 团体_妖怪 orange
11 上下级 blue
12 父子 blue
13 父女 blue
14 母子 blue
15 母女 blue
16 兄弟 lightblue
17 夫妻 green
18 兄弟 green
19 亲戚 lightgreen
20 组成 lightred

View File

@ -0,0 +1,19 @@
# cpic-portal
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

10990
SmartKG-master/SmartKGUI/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
{
"name": "cpic-portal",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"babel-polyfill": "^6.26.0",
"core-js": "^3.6.4",
"element-ui": "^2.13.0",
"vue": "^2.6.11",
"vue-router": "^3.1.5",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.2.0",
"@vue/cli-plugin-router": "^4.2.0",
"@vue/cli-plugin-vuex": "^4.2.0",
"@vue/cli-service": "^4.2.0",
"axios": "^0.19.2",
"echarts": "^4.6.0",
"vue-template-compiler": "^2.6.11"
}
}

View File

@ -0,0 +1,3 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
var urlapi = "http://localhost:5000"

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<!--
Copyright (c) Microsoft Corporation.
Licensed under the MIT license.
-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="SHORTCUT ICON" href="https://c.s-microsoft.com/favicon.ico?v2" type="image/x-icon" />
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<title>知识图谱</title>
<script src="config.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="app"></div>
</body>
</html>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Handle History Mode and custom 404/500" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

View File

@ -0,0 +1,32 @@
<template>
<div id="app">
<router-view/>
</div>
</template>
<style>
/*
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
*/
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1000 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -0,0 +1,403 @@
/*
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
*/
.main {
height: 100%;
overflow: hidden;
position: absolute;
top: 0;
left: 0;
right: 0;
}
.chart-page {
height: 100%;
background: #f3f3f3;
overflow: hidden;
}
.chart-wrap {
position: absolute;
top: 20px;
left: 20px;
background: none;
width: 400px;
}
.chart-result {
margin-top: 45px;
background: #ffffff;
border-radius: 5px;
box-shadow: 0 2px 3px #d8d8d8;
padding: 10px;
text-align: left;
}
.chart-result .item-list.close {
max-height: 0;
overflow: hidden;
margin: 0;
}
.expand {
max-height: 250px;
overflow: auto;
}
.chart-result .title {
background: #fefaf1;
padding: 5px 10px;
font-size: 14px;
margin-bottom: 10px;
}
.chart-result .item-list {
margin-top: 10px;
list-style: none;
background: #f6f6f6;
padding: 0 10px;
font-size: 14px;
margin-bottom: 10px;
transition: all 0.3s;
}
.chart-result .item-list li {
cursor: pointer;
}
.chart-result .result-num {
padding: 0 5px;
color: red;
}
.chart-result .item-list li {
line-height: 200%;
}
.control {
text-align: center;
font-size: 14px;
line-height: 200%;
margin-top: 3px;
}
.control-btn {
cursor: pointer;
}
.arrow {
width: 20px;
height: 20px;
display: inline-block;
background-size: 20px 20px;
background-repeat: no-repeat;
background-position: center center;
position: relative;
top: 5px;
transition: all 0.3s;
}
.down {
transform: rotate(0deg);
}
.up {
transform: rotate(180deg);
}
.chart-search {
height: 100px;
position: relative;
width: 400px;
/* background: #ffffff; */
border-radius: 5px;
/* box-shadow: 0 2px 3px #d8d8d8; */
}
.chart-search-text {
position: absolute;
top: 1px;
left: 20px;
line-height: 40px;
font-size: 15px;
color: #025cea;
cursor: pointer;
text-decoration: none;
}
.chart-search-div {
position: absolute;
top: 96px;
left: 0;
line-height: 25px;
width: 300px;
border-radius: 20px;
border: 1px solid #025cea;
background: #ffffff;
margin-top: 4px;
}
.chart-search-div input {
width: 100%;
height: 25px;
text-indent: 10px;
border: 0;
background: none;
outline: none;
font-size: 16px;
}
.chart-search-div .chart-search-btn {
position: absolute;
right: -1px;
top: 0;
height: 26px;
width: 26px;
text-align: center;
background: #025cea;
border: none;
border-radius: 20px;
color: #ffffff;
cursor: pointer;
background-size: 25px 25px;
background-position: center center;
outline: none;
background-image: url("../assets/zoom.png");
}
#echart {
width: 100%;
height: 100%;
}
.list-item {
padding-left: 20px;
}
#tip button {
padding: 0;
border: 0;
box-shadow: none;
position: fixed;
bottom: 0;
right: 0;
background: none;
width: 50px;
height: 50px;
}
.active {
background: #c0c0c0;
}
.bot {
height: 500px;
}
.bot-info-wrap {
position: relative;
margin: 10px 0;
clear: both;
}
.bot-icon {
position: absolute;
left: 6px;
top: 5px;
font-size: 18px;
}
.bot-info {
line-height: 180%;
max-width: 60%;
background: #f3f3f3;
border: 1px solid #ccc;
margin-left: 30px;
display: inline-block;
padding: 0 5px;
}
.user-info-wrap {
position: relative;
margin: 10px 0;
clear: both;
}
.user-icon {
position: absolute;
right: 6px;
top: 5px;
font-size: 18px;
}
.user-info {
margin-right: 30px;
line-height: 180%;
max-width: 60%;
background: #f3f3f3;
border: 1px solid #ccc;
padding: 0 5px;
float: right;
margin-bottom: 10px;
}
.header {
background-color: #0084FB;
}
.bot-wrap {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #f8f8f8;
z-index: 11;
display: flex;
flex-direction: column;
}
.bot {
width: 400px;
display: flex;
justify-content: space-around;
flex-grow: 1;
align-items: center;
background-size: cover;
}
.bot .left {
width: 70%;
display: flex;
align-items: left;
position: relative;
}
.bot .chat {
border: 1px solid #ccc;
margin: 0 auto;
width: 100%;
height: 523px;
background-color: #eee;
position: relative;
display: flex;
flex-direction: column;
overflow: hidden;
}
.bot .chat .send {
bottom: 0;
left: 0;
margin-top: 0;
}
.bot .chat .send .chat-input {
border: 0;
position: relative;
display: flex;
}
.bot .chat .send input {
height: 30px;
border: 0;
border: 1px solid #ddd;
box-sizing: border-box;
margin: 3px;
flex-grow: 1;
padding-right: 30px;
padding-left: 5px;
transition: all .2s;
}
.bot .chat .send input:focus {
border: 1px solid #0084FB;
}
.bot .chat .send input:focus+.btn>i {
color: #0084FB;
}
.bot .chat .send .btnsend {
position: absolute;
right: 10px;
height: 22px;
top: 4px;
cursor: pointer;
color: #0084FB;
font-size: 20px;
z-index: 333;
transition: all .2s;
}
.bot .chat .send .btn i {
font-size: 22px;
margin-top: 1px;
color: #ccc;
transition: all .2s;
}
.history {
width: 100%;
overflow: auto;
box-sizing: border-box;
padding: 5px;
flex-grow: 1;
background-color: #FAFAFA;
}
.history::-webkit-scrollbar {
width: 10px;
}
.history::-webkit-scrollbar-track {
border-radius: 5px;
background-color: #eee;
}
.history::-webkit-scrollbar-thumb {
border-radius: 5px;
background: #ccc;
}
.chat-title {
background: #0084FB;
height: 35px;
padding: 5px;
box-sizing: border-box;
position: relative;
box-shadow: 0px 0px 2px #000;
}
pre {
white-space: pre-wrap;
word-wrap: break-word;
font-size: 14px;
margin: 5px 0;
}
.btn-info {
padding: 2px 10px;
min-width: 70px;
height: 29px;
line-height: 26px;
}
.bot-title {
line-height: 26px;
color: #fff;
font-size: 14px;
padding-left: 10px;
}
.spinner {
display: inline-block;
position: relative;
top: 3px;
}
.el-popover.el-popper{
background: none;
padding: 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@ -0,0 +1,279 @@
* {
padding: 0;
margin: 0;
}
#progress {
height: 10px;
width: 500px;
border: 1px solid gold;
position: relative;
border-radius: 5px;
}
#progress .progress-item {
height: 100%;
position: absolute;
left: 0;
top: 0;
background: chartreuse;
border-radius: 5px;
transition: width .3s linear;
}
#upload {
position: relative;
width: 334px;
height: 40px;
margin: 0 auto;
}
#upload .upload-spin {
position: absolute;
left: 370px;
top: 1px;
}
#spin {
display: none;
}
#upload .upload-success {
display: inline-block;
width: 20px;
height: 20px;
text-align: center;
border-radius: 50%;
color: rgb(111, 172, 20);
position: absolute;
left: 370px;
top: 8px;
display: none;
}
#file {
position: absolute;
width: 250px;
height: 35px;
z-index: 1;
opacity: 0;
cursor: pointer;
}
#filetext {
position: absolute;
width: 250px;
height: 35px;
text-indent: 10px;
left: 0;
}
.container {
width: 50%;
margin: 0 auto;
border: 1px solid #ccc;
box-shadow: 1px 1px 1px #ccc;
margin-top: 30px;
border-radius: 5px;
padding: 20px;
margin-bottom: 30px;
}
#uploadfile {
position: absolute;
left: 270px;
top: 2px;
background-color: #409eff;
color: #fff;
height: 35px;
border-radius: 3px;
padding: 0 20px;
border: 1px solid #409eff;
cursor: pointer;
}
#uploadfile:hover {
background-color: #66b1ff;
}
.title {
line-height: 300%;
font-size: 16px;
color: #666;
padding-left: 10px;
text-align: center;
}
#log {
margin-top: 20px;
color: #666;
padding-left: 10px;
}
#log p {
color: #666;
line-height: 200%;
width: 400px;
text-align: left;
margin: 0 auto;
}
#download {
text-align: center;
margin: 20px;
}
#downloadbtn {
background-color: #409eff;
color: #fff;
height: 35px;
border-radius: 3px;
padding: 0 20px;
border: 1px solid #409eff;
cursor: pointer;
}
#downloadbtn:hover {
background-color: #66b1ff;
}
.list {
margin-bottom: 20px;
}
.list-item {
display: flex;
justify-content: space-between;
}
.modal-body {
position: relative;
padding: 30px;
}
.modal-header {
padding: 15px;
border-bottom: none;
}
.modal-footer {
padding: 15px;
text-align: right;
border-top: none;
}
.main {
display: block;
overflow: auto;
}
.layui-table tr th {
font-weight: bold;
font-size: 18px;
border: 1px solid #ccc;
line-height: 200%;
padding: 5px;
text-align: center;
}
.layui-table tr td {
font-size: 16px;
border: 1px solid #ccc;
line-height: 200%;
padding: 5px;
text-align: center;
}
.upload-spin img {
width: 40px;
}
.list li {
line-height: 200%;
margin-top: 20px;
}
.file {
width: 50%;
}
.file-item {
display: flex;
align-items: center;
margin-top: 10px;
}
.add-btn.el-icon-circle-plus-outline {
font-size: 20px;
display: block;
text-align: left;
margin-top: 10px;
font-size: 20px;
}
.color-p{
margin-top: 10px;
}
.color-item1{
display: inline-block;
width: 120px;
line-height: 180%;
}
.color-item2{
display: inline-block;
width: 120px;
line-height: 180%;
position: relative;
}
.color-item2 input{
background-color: #FFF;
background-image: none;
border-radius: 4px;
border: 1px solid #DCDFE6;
box-sizing: border-box;
color: #606266;
display: inline-block;
font-size: inherit;
height: 25px;
line-height: 25px;
outline: 0;
padding: 0 15px;
transition: border-color .2s cubic-bezier(.645,.045,.355,1);
width: 100%;
}
.color-block{
display: inline-block;
width: 13px;
height: 13px;
background: #409eff;
position: absolute;
top: 6px;
right: 10px;
}
.other-color{
margin-top: 20px;
color: #666;
}
.other-color .other-color-item{
display: inline-block;
position: relative;
width: 100px;
}
.other-color .other-color-item .color-block{
top: 1px;
left: 85px;
}
.error-info{
position:absolute;
right: -65px;
color: red;
font-size: 12px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import "babel-polyfill";
Vue.config.productionTip = false
Vue.use(ElementUI);
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')

View File

@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Upload from '../views/Upload.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/upload',
name: 'Upload',
component: () => import('../views/Upload.vue')
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router

View File

@ -0,0 +1,15 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
}
})

View File

@ -0,0 +1,544 @@
<template>
<div class="main">
<div class="chart-page">
<div id="echart" width="400" height="400"></div>
<div id="tip">
<el-popover
placement="bottom"
width="400"
trigger="click"
style="padding: 0 !important"
>
<div class="bot">
<div class="chat">
<div class="chat-title">
<span class="bot-title">SmartKG bot</span>
</div>
<div class="history" id="history">
<div v-for="item of histroyList" v-bind:key="item.key">
<div v-if="item.from == 'user'" class="user-info-wrap">
<div class="user-info">{{ item.info }}</div>
<i class="el-icon-user-solid user-icon"></i>
</div>
<div v-if="item.from == 'bot'" class="bot-info-wrap">
<i class="el-icon-service bot-icon"></i>
<div class="bot-info">
<pre>{{ item.info }}</pre>
</div>
</div>
</div>
</div>
<div class="send">
<div class="chat-input">
<input
v-model="currentText"
type="text"
id="curentChat"
style="border-radius: 5px"
v-on:keyup.enter="send"
/>
<div class="btnsend" @click="send()" title="send">
<i class="el-icon-chat-round"></i>
</div>
</div>
</div>
</div>
</div>
<el-button slot="reference">
<i class="el-icon-service" style="font-size: 30px"></i>
</el-button>
</el-popover>
</div>
<div class="chart-wrap">
<div class="chart-search">
<div class="chart-search-div">
<input
class="chart-search-input"
type="text"
:placeholder="
selectSce == '' ? '请先选择数据库和场景' : '请输入实体名称'
"
v-model="keyWord"
v-on:input="gotochart"
v-on:keyup.enter="gotochartEnter"
ref="search"
:disabled="selectSce == ''"
/>
<button
class="chart-search-btn"
@click="gotochartSmallBtn()"
></button>
</div>
<el-select
v-model="selectDataStore"
placeholder="请选择数据库"
style="left: -88px; width: 222px; margin-bottom: 10px"
:change="changeDataStore()"
>
<el-option
v-for="item in datastoreList"
:key="item.id"
:label="item.name"
:value="item.name"
></el-option>
</el-select>
<el-select
v-model="selectSce"
placeholder="请选择场景"
style="left: -88px; width: 222px"
:change="getScenColor()"
>
<el-option
v-for="item in scenariosList"
:key="item.id"
:label="item.name"
:value="item.name"
></el-option>
</el-select>
<el-button
@click="changeScen()"
style="left: 236px; top: 50px; position: absolute"
>展示</el-button
>
</div>
<div class="chart-result">
<p class="title" v-if="isExpand">
模糊搜索结果信息共找到
<span class="result-num">{{ list.length }}</span
>结果
</p>
<ul class="item-list" :class="{ close: !isExpand, expand: isExpand }">
<li
class="list-item"
style="justify-content: left"
v-for="item of list"
v-bind:key="item.id"
:class="{ active: item.id == currentId }"
@click="getNodes(item.id, item.name)"
v-html="changeListKey(item.name)"
></li>
</ul>
<hr v-if="isExpand" />
<div class="control">
<span class="control-btn" @click="isExpand = !isExpand">
全部收起
<span
class="arrow"
:class="{ up: isExpand, down: !isExpand }"
></span>
</span>
</div>
</div>
</div>
</div>
</div>
</template>
<style type="text/css" scoped>
@import "../assets/home.css";
</style>
<script>
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import axios from "axios";
import echarts from "echarts";
export default {
name: "Home",
data() {
return {
keyWord: "",
hotkeyList: [],
isExpand: true,
list: [],
nodes: [],
edges: [],
sendTime: new Date().getTime(),
timer: null,
charts: null,
currentId: "",
baseURL: window.urlapi,
scenariosList: [],
datastoreList: [],
colorList: [],
selectSce: "",
lastScen: "",
selectDataStore: "",
lastDataStore: "",
histroyList: [],
currentText: "",
sessionId: "",
};
},
components: {},
methods: {
send() {
if (this.currentText.trim() == "") {
return;
}
axios
.post(`${this.baseURL}/api/bot`, {
userId: "",
sessionId: this.sessionId,
datastoreName: this.selectDataStore,
query: this.currentText,
})
.then((res) => {
this.sessionId = res.data.sessionId;
this.histroyList.push({
from: "bot",
info: res.data.result.responseMessage,
key: new Date().valueOf(),
});
setTimeout(() => {
document.querySelector("#history").scrollTop = 99999;
}, 150);
});
this.histroyList.push({
from: "user",
info: this.currentText,
key: new Date().valueOf(),
});
this.currentText = "";
setTimeout(() => {
document.querySelector("#history").scrollTop = 99999;
}, 150);
},
getScenColor() {
if (this.selectSce == "" || this.selectSce == this.lastScen) {
return;
}
axios
.get(
`${this.baseURL}/api/Config/entitycolor?datastoreName=${encodeURI(
this.selectDataStore
)}&scenarioName=${encodeURI(this.selectSce)}`
)
.then((response) => {
for (let [key, value] of Object.entries(
response.data.entityColorConfig
)) {
this.colorList.push({ name: key, color: value });
}
});
},
changeScen() {
if (this.selectSce == "" || this.selectSce == this.lastScen) {
return;
}
this.lastScen = this.selectSce;
// axios
// .get(
// `${this.baseURL}/api/Graph/visulize?datastoreName=${encodeURI(
// this.selectDataStore
// )}&scenarioName=${encodeURI(this.selectSce)}`
// )
// .then((res) => {
// this.nodes = res.data.nodes;
// this.edges = res.data.relations;
// this.process();
// this.generate();
// });
axios
.get(
`${this.baseURL}/api/Graph/visulize?datastoreName=${encodeURI(
this.selectDataStore
)}&scenarioName=${encodeURI(this.selectSce)}`
)
.then((res) => {
if (res.data.success == false) {
alert(res.data.responseMessage);
} else {
this.nodes = res.data.nodes;
this.edges = res.data.relations;
this.process();
this.generate();
}
});
},
changeDataStore() {
if (
this.selectDataStore == "" ||
this.selectDataStore == this.lastDataStore
) {
return;
}
this.lastDataStore = this.selectDataStore;
this.getScenarios();
this.keyWord = "";
this.lastScen = "";
this.selectSce = "";
},
gotochartEnter() {
axios
.get(`${this.baseURL}/api/Search?keyword=${encodeURI(this.keyWord)}`)
.then((response) => {
this.currentId = response.data.nodes[0].id;
axios
.get(`${this.baseURL}/api/Search/${response.data.nodes[0].id}`)
.then((res) => {
this.nodes = res.data.nodes;
this.edges = res.data.relations;
this.process();
this.generate();
});
});
},
changeListKey(item) {
return item.replace(
new RegExp(this.keyWord, "g"),
`<span style='color:red'>${this.keyWord}</span>`
);
},
gotochartSmallBtn() {
this.gotochartEnter();
this.gotochart();
},
gotochart() {
if (this.keyWord != "") {
setTimeout(() => {
this.$refs.search.focus();
this.$refs.search.selectionStart = 100;
this.$refs.search.selectionEnd = 100;
}, 10);
}
this.timer = setTimeout(() => {
let now = new Date().getTime();
if (now - this.sendTime < 600 || this.keyWord == "") {
clearTimeout(this.timer);
return;
}
this.sendTime = new Date().getTime();
if (this.keyWord == "") {
return;
}
axios
.get(
`${this.baseURL}/api/Graph/search?datastoreName=${this.selectDataStore}&keyword=${this.keyWord}&scenarioName=${this.selectSce}`
)
.then((response) => {
if (response.data.nodes === null) {
this.list = [];
this.charts.dispose();
this.charts.hideLoading();
} else {
this.list = response.data.nodes;
}
});
}, 2000);
},
getNodes(id, name) {
// this.lastScen = "";
// this.selectSce = "";
this.currentId = id;
axios
.get(
`${this.baseURL}/api/Graph/relations/${id}?datastoreName=${this.selectDataStore}`
)
.then((res) => {
this.nodes = res.data.nodes;
this.edges = res.data.relations;
this.process();
this.generate();
this.charts.hideLoading();
});
},
generate() {
this.charts = echarts.init(document.getElementById("echart"));
var option = {
title: {
top: "bottom",
left: "right",
},
tooltip: {
trigger: "item",
formatter: (params, ticket) => {
if (params.data.fullname == undefined) {
return;
}
let str = "";
for (let count = 0; count < params.data.fullname.length; count++) {
str += params.data.fullname[count];
if (count % 20 == 0 && count != 0) {
str += "<br/>";
}
}
return str;
},
textStyle: {
width: "100px",
},
extraCssText: "text-align:left;",
},
draggable: true,
series: [
{
nodeScaleRatio: 0,
zoom: 1,
animation: false,
name: "Les Miserables",
type: "graph",
edgeSymbol: ["", "arrow"],
focusNodeAdjacency: true,
layout: "force",
force: {
initLayout: false,
layoutAnimation: false,
repulsion: 300,
edgeLength: 140,
gravity: 0.1,
},
edgeLabel: {
show: true,
},
data: this.nodes,
links: this.edges,
roam: true,
label: {
color: "#000",
normal: {
position: "right",
},
},
lineStyle: {
normal: {
curveness: 0.2,
},
},
},
],
};
this.charts.setOption(option);
if (this.charts) {
this.charts.off("click");
}
this.charts.on("click", (e) => {
this.charts = echarts.init(document.getElementById("echart"));
this.charts.showLoading({
text: "正在加载数据",
color: "none",
});
this.getChildNode(e.data).then(() => {
this.process();
option.series[0].data = this.nodes;
option.series[0].links = this.edges;
this.charts.setOption(option);
this.charts.resize({
width: "auto",
});
this.charts.hideLoading();
});
});
},
getChildNode(node) {
let url = "";
if (/属性/.test(node.info)) {
url = `${this.baseURL}/api/Graph/Search/property?name=${encodeURI(
node.displayName
)}&value=${encodeURI(node.name)}&datastoreName=${this.selectDataStore}`;
} else {
url = `${this.baseURL}/api/Graph/relations/${node.id}?datastoreName=${this.selectDataStore}`;
}
let promise = new Promise((resolve, reject) => {
axios({
method: "get",
url,
}).then((res) => {
this.nodes = res.data.nodes;
this.edges = res.data.relations;
this.process();
resolve();
});
});
return promise;
},
process() {
for (let i = 0; i < this.nodes.length; i++) {
this.nodes[i].draggable = false;
if (this.nodes[i].name.length > 7) {
if (!this.nodes[i].fullname) {
this.nodes[i].fullname = this.nodes[i].name;
this.nodes[i].name = this.nodes[i].name.substring(0, 6) + "...";
}
}
if (this.nodes[i].info == undefined) {
this.nodes[i].info = this.nodes[i].label;
}
this.nodes[i].label = {
show: true,
position: "bottom",
width: "30",
color: "#000",
};
this.nodes[i].symbolSize = 30;
if (this.nodes[i].name == "true") {
this.nodes[i].symbolSize = 10;
this.nodes[i].label = { show: false };
}
this.nodes[i].itemStyle = {
color: "#cccccc",
borderColor: "#cccccc",
shadowColor: "rgba(0, 0, 0, 0.5)",
shadowBlur: 3,
};
for (let k = 0; k < this.colorList.length; k++) {
if (this.nodes[i].info == this.colorList[k].name) {
this.nodes[i].itemStyle = {
color: this.colorList[k].color,
borderColor: "#ffffff",
shadowColor: "rgba(0, 0, 0, 0.5)",
shadowBlur: 3,
};
this.nodes[i].label.color = this.colorList[k].color;
}
}
}
for (let i = 0; i < this.edges.length; i++) {
this.edges[i].source = this.edges[i].sourceId;
this.edges[i].target = this.edges[i].targetId;
for (let j = 0; j < this.nodes.length; j++) {
if (this.edges[i].target == this.nodes[j].id)
this.edges[i].lineStyle = {
width: 2,
color: "#000000",
};
}
this.edges[i].label = {
formatter: this.edges[i].value,
};
}
},
getScenarios() {
this.scenariosList = [];
axios
.get(
`${this.baseURL}/api/Graph/scenarios?datastoreName=${this.selectDataStore}`
)
.then((response) => {
for (let i = 0; i < response.data.scenarioNames.length; i++) {
this.scenariosList.push({
id: i,
name: response.data.scenarioNames[i],
});
}
});
},
getDataStore() {
this.datastoreList = [];
axios.get(`${this.baseURL}/api/DataStoreMgmt`).then((response) => {
for (let i = 0; i < response.data.datastoreNames.length; i++) {
this.datastoreList.push({
id: i,
name: response.data.datastoreNames[i],
});
}
});
},
},
mounted() {
this.getDataStore();
},
};
</script>

View File

@ -0,0 +1,471 @@
<template>
<div class="main">
<div class="container">
<p class="title">请您选择数据仓库</p>
<div id="download">
<div class="list">
<!-- <div v-for="item of dataStores" v-bind:key="item.key">
<div class="list-item">
<el-radio
v-model="radio"
:label="item.name"
border
style="margin-bottom: 10px"
>
{{ item.name }}
<i
class="el-icon-s-flag"
v-if="item.name == defaultDataStore"
></i>
</el-radio>
<el-button
type="primary"
@click="openUploadwin(item.name)"
style="height: 40px"
>上传数据</el-button
>
</div>
</div> -->
<el-select
v-model="radio"
placeholder="请选择数据库"
:change="getDataStore()"
>
<el-option
v-for="item in dataStores"
:key="item.id"
:label="item.name"
:value="item.name"
></el-option>
</el-select>
</div>
<el-button type="primary" @click="dialogCreateVisible = true"
>新建数据仓库</el-button
>
<el-button type="primary" @click="openDel()">删除仓库</el-button>
<el-button type="primary" @click="openUploadwin(radio)"
>上传数据</el-button
>
<el-button type="primary" @click="reloadData()">加载数据</el-button>
<el-button type="primary" @click="colorVisible = true"
>设置颜色</el-button
>
<el-button type="primary" @click="download()">下载模板</el-button>
<el-dialog
title="新建数据库"
:visible.sync="dialogCreateVisible"
width="30%"
>
<p>请输入数据仓库的名称</p>
<p>
<el-input
v-model="input"
placeholder="请输入仓库名称"
style="width: 60%; margin-top: 20px"
></el-input>
</p>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogCreateVisible = false"> </el-button>
<el-button type="primary" @click="saveDataStore()"> </el-button>
</span>
</el-dialog>
<!-- -->
<el-dialog title="设置颜色" :visible.sync="colorVisible" width="40%">
<div style="margin-bottom: 20px">
<el-select
v-model="selectDataStore"
placeholder="请选择数据库"
:change="changeDataStore()"
>
<el-option
v-for="item in dataStores"
:key="item.id"
:label="item.name"
:value="item.name"
></el-option>
</el-select>
<el-select
v-model="selectSce"
placeholder="请选择场景"
:change="changeScen()"
>
<el-option
v-for="item in scenariosList"
:key="item.id"
:label="item.name"
:value="item.name"
></el-option>
</el-select>
</div>
<p v-for="item in colorList" :key="item.id" class="color-p">
<span class="color-item1">{{ item.name }}</span>
<span class="color-item2">
<input
v-model="item.color"
type="text"
autocomplete="off"
placeholder="请输入颜色数值"
class="el-input__inner"
/>
<span
class="color-block"
v-bind:style="{ background: item.color }"
></span>
<span v-if="checkColor(item.color)" class="error-info">
格式错误!</span
>
</span>
</p>
<div class="other-color">
<h5 v-if="otherColorList.length > 0" style="margin-bottom: 10px">
其他备选颜色
</h5>
<span
v-for="item in otherColorList"
:key="item.id"
class="other-color-item"
>
<span>{{ item.color }}</span>
<span
class="color-block"
v-bind:style="{ background: item.color }"
></span>
</span>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="colorVisible = false"> </el-button>
<el-button type="primary" @click="saveColor()"> </el-button>
</span>
</el-dialog>
<!-- -->
<el-dialog
title="删除数据库"
:visible.sync="dialogDelVisible"
width="30%"
>
<p>您确实要删除这个数据仓库吗</p>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogDelVisible = false"> </el-button>
<el-button type="primary" @click="del()"> </el-button>
</span>
</el-dialog>
<el-dialog
title="上传数据"
:visible.sync="dialogUploadVisible"
width="30%"
>
<div
class="file-item"
v-for="item of uploadFiles"
v-bind:key="item.key"
>
<el-input
v-model="item.scenario"
size="small"
placeholder="请输入场景名称"
style="width: 40%; margin-right: 30px"
></el-input>
<input class="file" type="file" @change="getFile($event, item)" />
</div>
<div>
<i
class="add-btn el-icon-circle-plus-outline"
@click="addFile()"
></i>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogUploadVisible = false"> </el-button>
<el-button type="primary" @click="uploadSend()"> </el-button>
</span>
</el-dialog>
</div>
</div>
</div>
</template>
<style type="text/css" scoped>
@import "../assets/upload.css";
</style>
<script>
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import axios from "axios";
import qs from "qs";
export default {
name: "Upload",
data() {
return {
baseURL: window.urlapi,
dataStores: [],
dialogCreateVisible: false,
dialogDefaultVisible: false,
dialogDelVisible: false,
dialogUploadVisible: false,
colorVisible: false,
input: "",
radio: "",
uploadFiles: [],
defaultDataStore: "",
selectDataStore: "",
lastDataStore: "",
scenariosList: [],
selectSce: "",
colorList: [],
otherColorList: [],
lastScen: "",
lastDataStore: "",
selectRadioDataStore: "",
};
},
components: {},
methods: {
handleClose(done) {
this.$confirm("确认关闭?")
.then((_) => {
done();
})
.catch((_) => {});
},
saveDataStore() {
axios
.post(`${this.baseURL}/api/DataStoreMgmt`, {
datastoreName: this.input,
})
.then((res) => {
this.input = "";
this.getList();
this.dialogCreateVisible = false;
});
},
openDel() {
if (this.radio == "") {
alert("请选择要删除的数据库");
return;
}
this.dialogDelVisible = true;
},
reloadData() {
if (this.radio == "") {
alert("请选择要加载的数据库");
return;
}
axios
.post(
`${this.baseURL}/api/DataStoreMgmt/preprocess/reload`,
qs.stringify({ DatastoreName: this.radio })
)
.then((res) => {
console.log(res);
});
},
changeScen() {
if (this.selectSce == "" || this.selectSce == this.lastScen) {
return;
}
this.lastScen = this.selectSce;
axios
.get(
`${this.baseURL}/api/Config/entitycolor?datastoreName=${encodeURI(
this.selectDataStore
)}&scenarioName=${encodeURI(this.selectSce)}`
)
.then((response) => {
this.colorList = [];
for (let [key, value] of Object.entries(
response.data.entityColorConfig
)) {
this.colorList.push({ name: key, color: value });
}
console.log(this.colorList);
axios.get(`${this.baseURL}/api/Config/colors`).then((res) => {
this.otherColorList = [];
for (let [key, value] of Object.entries(res.data.colors)) {
this.otherColorList.push({ name: key, color: value });
}
});
});
},
saveColor() {
let str = "";
for (let i = 0; i < this.colorList.length; i++) {
if (this.checkColor(this.colorList[i].color)) {
alert("颜色格式错误");
return false;
}
str +=
"&" +
encodeURI(this.colorList[i].name) +
"=" +
encodeURIComponent(this.colorList[i].color);
}
axios
.post(
`${
this.baseURL
}/api/Config/entitycolor?user=skuser1&datastoreName=${encodeURI(
this.selectDataStore
)}&scenarioName=${encodeURI(this.selectSce)}${str}`,
{}
)
.then((res) => {
alert("颜色设置保存成功");
this.colorVisible = false;
this.colorList = [];
this.selectDataStore = "";
this.selectSce = "";
this.otherColorList = [];
this.lastScen = "";
this.selectSce = "";
});
},
checkColor(color) {
return /^#([0-9a-fA-F]{6})$/.test(color) ? false : true;
},
//
getDataStore() {
// this.radio = this.r
},
changeDataStore() {
if (
this.selectDataStore == "" ||
this.selectDataStore == this.lastDataStore
) {
return;
}
this.lastDataStore = this.selectDataStore;
this.getScenarios();
this.lastScen = "";
this.selectSce = "";
},
getScenarios() {
this.scenariosList = [];
axios
.get(
`${this.baseURL}/api/Graph/scenarios?datastoreName=${this.selectDataStore}`
)
.then((response) => {
for (let i = 0; i < response.data.scenarioNames.length; i++) {
this.scenariosList.push({
id: i,
name: response.data.scenarioNames[i],
});
}
});
},
//
download() {
window.location.href = `./SmartKG_KGDesc_Template.xlsx`;
},
getList() {
this.dataStores = [];
axios.get(`${this.baseURL}/api/DataStoreMgmt`).then((res) => {
for (let i = 0; i < res.data.datastoreNames.length; i++) {
this.dataStores.push({
name: res.data.datastoreNames[i],
});
}
});
},
del() {
let config = {
headers: {
accept: "text/plain",
"Content-Type": "application/json-patch+json",
},
data: { datastoreName: this.radio },
};
axios.delete(`${this.baseURL}/api/DataStoreMgmt`, config).then((res) => {
this.getList();
this.dialogDelVisible = false;
this.radio = "";
});
},
getFile(event, item) {
item.file = event.target.files[0];
},
openUploadwin(name) {
if (this.radio == "") {
alert("请选择要上传的数据库");
return;
}
this.currentDataStore = name;
this.uploadFiles = [];
this.uploadFiles.push({ scenario: "", file: "" });
this.dialogUploadVisible = true;
},
addFile() {
this.uploadFiles.push({ scenario: "", file: "" });
},
uploadSend() {
let result = [];
console.log(this.uploadFiles.length);
for (let i = 0; i < this.uploadFiles.length; i++) {
let formData = new FormData();
formData.append("DatastoreName", this.currentDataStore);
formData.append("Scenario", this.uploadFiles[i].scenario);
formData.append("UploadFile", this.uploadFiles[i].file);
let config = {
headers: {
"Content-Type": "multipart/form-data",
},
};
setTimeout(() => {
axios
.post(
`${this.baseURL}/api/DataStoreMgmt/preprocess/upload`,
formData,
config
)
.then((res) => {
if (res.data.success == false) {
alert(res.data.responseMessage);
this.dialogUploadVisible = false;
} else {
result.push(true);
}
});
}, i * 1000);
}
let timer = setInterval(() => {
if (result.length == this.uploadFiles.length) {
if (result.every((item) => item == true)) {
alert("上传成功");
this.dialogUploadVisible = false;
this.radio = "";
let formData = new FormData();
formData.append("DatastoreName", this.currentDataStore);
axios
.post(
`${this.baseURL}/api/DataStoreMgmt/preprocess/reload`,
formData
)
.then((res) => {});
} else {
alert("上传失败");
}
clearInterval(timer);
}
}, 500);
},
},
mounted() {
this.getList();
},
};
</script>

View File

@ -0,0 +1,15 @@
FROM python36
COPY aspnetcore-runtime-2.1.16-linux-x64.tar.gz /data/
RUN mkdir -p /dotnet && \
tar zxf /data/aspnetcore-runtime-2.1.16-linux-x64.tar.gz -C /dotnet
ENV PATH=/dotnet:$PATH \
ASPNETCORE_URLS=http://+:8080 \
DOTNET_RUNNING_IN_CONTAINER=true \
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true
EXPOSE 8080
CMD ["/bin/bash"]

View File

@ -0,0 +1,16 @@
version: '2.3'
services:
aspnetcore:
image: aspnetcore
build: ./aspnetcore/
smartkg:
image: smartkg
build: ./smartkg/
ports:
- 8082:8080
ui:
image: ui
build: ./ui/
ports:
- 8083:8080

View File

@ -0,0 +1,28 @@
version: '2.3'
services:
aspnetcore:
image: aspnetcore
build: ./aspnetcore/
mongo:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: dialogdatabase
MONGO_INITDB_ROOT_PASSWORD: erN9XzDa785DSKrB
volumes:
# Persist data
- ./MongoData:/data/db
ports:
- 27000:27017
smartkg:
image: smartkg
build: ./smartkg/
ports:
- 8082:8080
ui:
image: ui
build: ./ui/
ports:
- 8083:8080

View File

@ -0,0 +1,27 @@
version: '2.3'
services:
aspnetcore:
image: aspnetcore
build: ./aspnetcore/
mongo:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: dialogdatabase
MONGO_INITDB_ROOT_PASSWORD: erN9XzDa785DSKrB
volumes:
# Persist data
- ./MongoData:/data/db
ports:
- 27000:27017
smartkg:
image: smartkg
build: ./smartkg/
ports:
- 8082:8080
ui:
image: ui
build: ./ui/
ports:
- 8083:8080

View File

@ -0,0 +1,23 @@
FROM aspnetcore
ARG DOCKER_HOST
COPY requirements.txt /tmp/
RUN pip install -r /tmp/requirements.txt
COPY SmartKGLocalBase.zip /tmp/
RUN unzip /tmp/SmartKGLocalBase.zip -d /app
COPY smartkg.zip /tmp/
RUN unzip /tmp/smartkg.zip -d /app
COPY appsettings.json /app/smartkg/
RUN sed -i "s/localhost/${DOCKER_HOST}/g" /app/smartkg/appsettings.json
ENV PATH=/opt/rh/rh-python36/root/usr/bin:$PATH \
LD_LIBRARY_PATH=/app/smartkg/lib64:$LD_LIBRARY_PATH
CMD cd /app/smartkg && \
dotnet SmartKG.KGBot.dll

View File

@ -0,0 +1,55 @@
{
"RunningMode": "Production",
"PersistanceType": "MongoDB",
"ConnectionStrings": {
"MongoDbConnection": "mongodb://dialogdatabase:erN9XzDa785DSKrB@localhost:27000",
"DataStoreMgmtDatabaseName": "DataStoreMgmt",
"ContextDatabaseName": "KGbot_Context"
},
"FileUploadConfig": {
"ColorConfigPath":"/app/SmartKGLocalBase/config",
"ExcelDir": "/app/SmartKGLocalBase/temp"
},
"KGDisplayConfig": {
"MaxEntityNumOfScenarioToDisplay": 200
},
"Scenarios": [
{
"ScenarioName": "MotionAndPower",
"MaxOptions": 3,
"Slots": []
}
],
"Logging": {
"LogLevel": {
"Default": "Information"
}
},
"AllowedHosts": "*",
"Serilog": {
"MinimumLevel": "Information",
"Override": {
"Microsoft": "Warning"
},
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"WriteTo": [
{
"Name": "RollingFile",
"Args": {
"pathFormat": "/applog/SmartKG.KGBot-{Date}.log",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level}] <{SourceContext} : {MemberName}() - line{LineNumber}> {Message} {NewLine} {Exception}",
"fileSizeLimitBytes": 104857600,
"rollOnFileSizeLimit": true,
"retainedFileCountLimit": 20
}
}
],
"Properties": {
"Application": "SmartKG.KGBot Web Service",
"ServiceType": "Chatbot based on KG"
}
}
}

View File

@ -0,0 +1,47 @@
{
"RunningMode": "Production",
"PersistanceType": "File",
"FileDataPath": {
"RootPath": "..\\SmartKGLocalBase\\DataStores",
"ContextFilePath": "..\\SmartKGLocalBase\\kgbot_context.json"
},
"FileUploadConfig": {
"ColorConfigPath": "..\\SmartKGLocalBase\\config",
"ExcelDir": "..\\SmartKGLocalBase\\temp"
},
"KGDisplayConfig": {
"MaxEntityNumOfScenarioToDisplay": 200
},
"Logging": {
"LogLevel": {
"Default": "Information"
}
},
"AllowedHosts": "*",
"Serilog": {
"MinimumLevel": "Information",
"Override": {
"Microsoft": "Warning"
},
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"WriteTo": [
{
"Name": "RollingFile",
"Args": {
"pathFormat": "/applog/SmartKG.KGBot-{Date}.log",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level}] <{SourceContext} : {MemberName}() - line{LineNumber}> {Message} {NewLine} {Exception}",
"fileSizeLimitBytes": 104857600,
"rollOnFileSizeLimit": true,
"retainedFileCountLimit": 20
}
}
],
"Properties": {
"Application": "SmartKG.KGBot Web Service",
"ServiceType": "Chatbot based on KG"
}
}
}

View File

@ -0,0 +1,48 @@
{
"RunningMode": "Production",
"PersistanceType": "MongoDB",
"ConnectionStrings": {
"MongoDbConnection": "mongodb://dialogdatabase:erN9XzDa785DSKrB@104.214.140.219:27000",
"DataStoreMgmtDatabaseName": "DataStoreMgmt",
"ContextDatabaseName": "KGbot_Context"
},
"FileUploadConfig": {
"ColorConfigPath": "..\\SmartKGLocalBase\\config",
"ExcelDir": "..\\SmartKGLocalBase\\temp"
},
"KGDisplayConfig": {
"MaxEntityNumOfScenarioToDisplay": 200
},
"Logging": {
"LogLevel": {
"Default": "Information"
}
},
"AllowedHosts": "*",
"Serilog": {
"MinimumLevel": "Information",
"Override": {
"Microsoft": "Warning"
},
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"WriteTo": [
{
"Name": "RollingFile",
"Args": {
"pathFormat": "/applog/SmartKG.KGBot-{Date}.log",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level}] <{SourceContext} : {MemberName}() - line{LineNumber}> {Message} {NewLine} {Exception}",
"fileSizeLimitBytes": 104857600,
"rollOnFileSizeLimit": true,
"retainedFileCountLimit": 20
}
}
],
"Properties": {
"Application": "SmartKG.KGBot Web Service",
"ServiceType": "Chatbot based on KG"
}
}
}

View File

@ -0,0 +1,4 @@
xlrd
xlsxwriter
argparse

View File

@ -0,0 +1,12 @@
FROM node
ARG DOCKER_HOST
COPY smartkgui.zip /tmp/
RUN unzip /tmp/smartkgui.zip -d /app
COPY config.js /app/smartkgui/public/
RUN sed -i "s/localhost/${DOCKER_HOST}/g" /app/smartkgui/public/config.js
CMD cd /app/smartkgui && npm i && npm run serve

View File

@ -0,0 +1,3 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
var urlapi = "http://localhost:8082"

View File

@ -0,0 +1,3 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
var urlapi = "http://localhost:5000"

View File

@ -0,0 +1,79 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using SmartKG.Common.Data;
using Microsoft.Extensions.Configuration;
using Serilog;
using SmartKG.Common.Logger;
using SmartKG.Common.Data.Configuration;
namespace SmartKG.Common.ContextStore
{
public class ContextAccessor
{
private static ContextAccessor uniqueInstance;
private IContextAccessor accessor;
private ILogger log;
private ContextAccessor(IConfiguration config)
{
log = Log.Logger.ForContext<ContextAccessor>();
string persistanceType = config.GetSection("PersistanceType").Value;
log.Here().Information("PersistanceType is " + persistanceType);
if (persistanceType == "File")
{
FilePathConfig filePaths = config.GetSection("FileDataPath").Get<FilePathConfig>();
string contextPath = filePaths.ContextFilePath;
this.accessor = new ContextFileAccessor(contextPath);
this.accessor.CleanContext();
}
else
{
string connectionString = config.GetConnectionString("MongoDbConnection");
string dbName = config.GetConnectionString("ContextDatabaseName");
this.accessor = new ContextDBAccessor(connectionString, dbName);
this.accessor.CleanContext();
}
}
public static ContextAccessor GetInstance()
{
return uniqueInstance;
}
public static ContextAccessor initInstance(IConfiguration config)
{
if (uniqueInstance == null)
{
uniqueInstance = new ContextAccessor(config);
}
return uniqueInstance;
}
public (bool, DialogContext) GetContext(string userId, string sessionId)
{
return this.accessor.GetContext(userId, sessionId);
}
public void UpdateContext(string userId, string sessionId, DialogContext context)
{
this.accessor.UpdateContext(userId, sessionId, context);
}
public void CleanContext()
{
this.accessor.CleanContext();
}
}
}

View File

@ -0,0 +1,91 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using SmartKG.Common.Data;
using MongoDB.Driver;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using SmartKG.Common.Logger;
using MongoDB.Bson;
namespace SmartKG.Common.ContextStore
{
public class ContextDBAccessor : IContextAccessor
{
private ILogger log;
private IMongoCollection<DialogContext> collection;
int MAX_DURATION_INVALID_INPUT = 3;
public ContextDBAccessor(string connectionString, string dbName) {
log = Log.Logger.ForContext<ContextDBAccessor>();
MongoClient client = new MongoClient(connectionString);
IMongoDatabase db = client.GetDatabase(dbName);
this.collection = db.GetCollection<DialogContext>("Contexts");
log.Here().Information("Context in MongoDB. connectionString: " + connectionString + ", ContextDatabaseName: " + dbName);
}
public (bool, DialogContext) GetContext(string userId, string sessionId)
{
bool newlyCreated = true;
DialogContext context = null;
try
{
var results = collection.FindAsync(x => x.userId == userId && x.sessionId == sessionId).Result;
List<DialogContext> contexts = null;
if (results != null)
{
contexts = results.ToList<DialogContext>();
}
if (contexts != null && contexts.Count() > 0)
{
context = contexts[0];
newlyCreated = false;
}
else
{
context = new DialogContext(userId, sessionId, MAX_DURATION_INVALID_INPUT);
this.collection.InsertOneAsync(context);
}
}
catch (Exception e)
{
log.Error(e, e.Message);
throw (e);
}
return (newlyCreated, context);
}
public bool UpdateContext(string userId, string sessionId, DialogContext context)
{
try
{
this.collection.ReplaceOneAsync<DialogContext>(x => x.userId == userId && x.sessionId == sessionId, context);
}
catch (Exception e)
{
Log.Error(e, e.Message);
throw (e);
}
return true;
}
public void CleanContext()
{
BsonDocument allFilter = new BsonDocument();
this.collection.DeleteMany(allFilter);
this.collection.InsertOne(new DialogContext("000", "000", 3));
}
}
}

View File

@ -0,0 +1,148 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using SmartKG.Common.Data;
using Newtonsoft.Json;
using System;
using System.IO;
namespace SmartKG.Common.ContextStore
{
public class ContextFileAccessor : IContextAccessor
{
private string filePath;
int MAX_DURATION_INVALID_INPUT = 3;
public ContextFileAccessor(string filePath)
{
this.filePath = filePath;
}
private string GetKey(string userId, string sessionId)
{
if (string.IsNullOrWhiteSpace(userId))
{
userId = "";
}
if (string.IsNullOrWhiteSpace(sessionId))
{
sessionId = "";
}
return userId + "_" + sessionId;
}
public (bool, DialogContext) GetContext(string userId, string sessionId)
{
DialogContext context = null;
if (File.Exists(filePath))
{
string content = File.ReadAllText(filePath);
string[] lines = content.Split('\n');
foreach (string line in lines)
{
if (string.IsNullOrWhiteSpace(line))
{
continue;
}
string[] tmps = line.Split("\t");
if (tmps.Length != 2)
{
throw new Exception("Context File is invalid.");
}
string key = tmps[0];
string contextJsonStr = tmps[1];
if (string.IsNullOrWhiteSpace(key))
{
throw new Exception("Context Key cannot be empty.");
}
if (key == GetKey(userId, sessionId))
{
return (false, JsonConvert.DeserializeObject<DialogContext>(contextJsonStr));
}
}
context = new DialogContext(userId, sessionId, MAX_DURATION_INVALID_INPUT);
string newLine = GetKey(userId, sessionId) + "\t" + JsonConvert.SerializeObject(context) + Environment.NewLine;
File.AppendAllText(this.filePath, newLine);
return (true, context);
}
else
{
context = new DialogContext(userId, sessionId, MAX_DURATION_INVALID_INPUT);
string newLine = GetKey(userId, sessionId) + "\t" + JsonConvert.SerializeObject(context) + Environment.NewLine;
File.WriteAllText(this.filePath, newLine);
return (true, context);
}
}
public bool UpdateContext(string userId, string sessionId, DialogContext context)
{
if (!File.Exists(filePath))
{
throw new Exception("Context File doesn't exist. Cannot update context into it.");
}
string content = File.ReadAllText(filePath);
string[] lines = content.Split('\n');
string newContent = "";
foreach (string line in lines)
{
if (string.IsNullOrWhiteSpace(line))
{
continue;
}
string[] tmps = line.Split("\t");
if (tmps.Length != 2)
{
throw new Exception("Context File is invalid.");
}
string key = tmps[0];
string contextJsonStr = tmps[1];
if (string.IsNullOrWhiteSpace(key))
{
throw new Exception("Context Key cannot be empty.");
}
if (key == GetKey(userId, sessionId))
{
newContent += key + "\t" + JsonConvert.SerializeObject(context) + Environment.NewLine;
}
else
{
newContent += line + Environment.NewLine;
}
}
File.WriteAllText(this.filePath, newContent);
return true;
}
public void CleanContext()
{
File.WriteAllText(this.filePath, "");
}
}
}

View File

@ -0,0 +1,257 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using SmartKG.Common.Data;
using MongoDB.Driver;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using SmartKG.Common.Data.KG;
using SmartKG.Common.Logger;
using SmartKG.Common.Data.LU;
namespace SmartKG.Common.ContextStore
{
public class ContextManager : KGBotLogHandler
{
public const int MAX_DURATION_INVALID_INPUT = 3;
private DialogContext context;
private string userId;
private string sessionId;
private string datastoreName;
private ContextAccessor accController = ContextAccessor.GetInstance();
private ILogger log;
public ContextManager(string datastoreName, string userId, string sessionId)
{
this.datastoreName = datastoreName;
this.userId = userId;
this.sessionId = sessionId;
log = Log.Logger.ForContext<ContextManager>();
}
public void LogInformation(ILogger log, string title, string content)
{
log.Information("userId: " + this.userId + ", sessionId:" + this.sessionId + "\n" + title + " " + content);
}
public void LogError(ILogger log, Exception e)
{
log.Error("userId: " + this.userId + ", sessionId:" + this.sessionId + "\n" + e.Message, e);
}
public bool GetContext()
{
(bool isNewlyCreated, DialogContext aContext) = accController.GetContext(userId, sessionId);
if (isNewlyCreated)
{
aContext.datastoreName = this.datastoreName;
}
else
{
if (aContext.datastoreName != this.datastoreName)
{
if (aContext.status != DialogStatus.PENDING)
{
this.context = aContext;
return false;
}
else
aContext.datastoreName = this.datastoreName;
}
}
this.context = aContext;
return true;
}
public void UpdateContext()
{
accController.UpdateContext(this.userId, this.sessionId, this.context);
return;
}
public string GetStartVertexName()
{
return this.context.startVertexName;
}
public void SetStartVertexName(string name)
{
this.context.startVertexName = name;
}
public int GetMaxDurationTime()
{
return MAX_DURATION_INVALID_INPUT;
}
public int GetCurrentSlotSeqNum()
{
return this.context.currentSlotSeqNum;
}
public bool DureInvalidInput()
{
this.context.currentDurationTime -= 1;
if (this.context.currentDurationTime >= 0)
return true;
else
return false;
}
public void RefreshDurationTime()
{
this.context.currentDurationTime = MAX_DURATION_INVALID_INPUT;
}
public void SaveQuestion(string question)
{
LogInformation(log.Here(), "saved question:", question);
this.context.question = question;
}
public string GetQuestion()
{
return this.context.question;
}
public bool IsAllSlotsFilled()
{
if (this.context.slots == null)
return true;
if (this.context.currentSlotSeqNum < this.context.slots.Count())
return false;
else
return true;
}
public void AddAttributeFilterCondition(AttributePair attribute)
{
LogInformation(log.Here(), "get attribute:", JsonConvert.SerializeObject(attribute));
string key = attribute.attributeName;
if (this.context.savedAttributes.Keys.Contains(key))
{
this.context.savedAttributes[key] = attribute;
}
else
{
this.context.savedAttributes.Add(key, attribute);
}
}
public List<AttributePair> GetSavedAttributes()
{
return this.context.savedAttributes.Values.ToList();
}
public void SetSlots(List<DialogSlot> slots)
{
this.context.slots = slots;
}
public DialogSlot GetSlot(int stepNum)
{
if (stepNum > this.context.slots.Count())
{
return null;
}
else
{
return this.context.slots[stepNum - 1];
}
}
public void SetIntent(string intent)
{
this.context.intent = intent;
}
public void AddEntity(Object entity)
{
this.context.entities.Add(entity);
}
public void SetCandidates(Dictionary<int, Vertex> candidates)
{
LogInformation(log.Here(), "set candidates:", JsonConvert.SerializeObject(candidates));
this.context.vertexCandidates = candidates;
}
public string GetIntent()
{
return this.context.intent;
}
public void SetScenarioName(string scenarioName)
{
this.context.scenarioName = scenarioName;
}
public string GetSecnarioName()
{
return this.context.scenarioName;
}
public List<Object> GetEntities()
{
return this.context.entities;
}
public Dictionary<int, Vertex> GetCandidates()
{
return this.context.vertexCandidates;
}
public void StartDialog()
{
LogInformation(log.Here(), "start a dialog", "");
this.context.status = DialogStatus.INPROCESS;
}
public void EnterSlotFilling()
{
LogInformation(log.Here(), "begine to fill slots", "");
this.context.status = DialogStatus.SLOTFILLING;
this.context.currentSlotSeqNum = 1;
}
public void ForwardSlotFilling()
{
LogInformation(log.Here(), "slot [" + this.context.currentSlotSeqNum.ToString() + "]", "is processed");
this.context.currentSlotSeqNum += 1;
}
public DialogStatus GetStatus()
{
return this.context.status;
}
public void ExitDialog()
{
LogInformation(log.Here(), "exit dialog", "");
this.context.datastoreName = null;
this.context.vertexCandidates = null;
this.context.status = DialogStatus.PENDING;
this.context.slots = null;
this.context.currentSlotSeqNum = 0;
this.context.savedAttributes = new Dictionary<string, AttributePair>();
this.context.currentDurationTime = MAX_DURATION_INVALID_INPUT;
this.context.question = null;
this.context.intent = null;
this.context.startVertexName = null;
this.context.scenarioName = null;
}
}
}

View File

@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using SmartKG.Common.Data;
namespace SmartKG.Common.ContextStore
{
public interface IContextAccessor
{
(bool, DialogContext) GetContext(string userId, string sessionId);
bool UpdateContext(string userId, string sessionId, DialogContext context);
void CleanContext();
}
}

View File

@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SmartKG.Common.Data.Configuration
{
public class FilePathConfig
{
public string RootPath { get; set; }
public string DefaultDataStore { get; set; }
public string ContextFilePath { get; set; }
}
}

View File

@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace SmartKG.Common.Data.Configuration
{
public class FileUploadConfig
{
public string PythonEnvPath { get; set; }
public string ConvertScriptPath { get; set; }
public string ColorConfigPath { get; set; }
public string ExcelDir { get; set; }
}
}

View File

@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace SmartKG.Common.Data.Configuration
{
public class KGDisplayConfig
{
public int MaxEntityNumOfScenarioToDisplay { get; set; } = 150;
}
}

View File

@ -0,0 +1,14 @@
using MongoDB.Bson.Serialization.Attributes;
using System;
using System.Collections.Generic;
using System.Text;
namespace SmartKG.Common.Data
{
[BsonIgnoreExtraElements]
public class DatastoreItem
{
public string name { get; set; }
public string creator { get; set; }
}
}

View File

@ -0,0 +1,63 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson.Serialization.Options;
using SmartKG.Common.Data;
using SmartKG.Common.Data.KG;
using SmartKG.Common.Data.LU;
using System;
using System.Collections.Generic;
namespace SmartKG.Common.Data
{
public enum RUNNINGMODE
{
PRODUCTION, DEVELOPMENT
}
public enum DialogStatus
{
PENDING, SLOTFILLING, INPROCESS
}
[BsonIgnoreExtraElements]
public class DialogContext
{
public string datastoreName { get; set; }
public DialogStatus status { get; set; }
public string intent { get; set; }
public string scenarioName { get; set; }
public List<Object> entities { get; set; }
[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
public Dictionary<int, Vertex> vertexCandidates { get; set; }
public List<DialogSlot> slots { get; set; }
public int currentSlotSeqNum { get; set; }
[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
public Dictionary<string, AttributePair> savedAttributes { get; set; }
public string startVertexName { get; set; }
public int currentDurationTime { get; set; }
public string question { get; set; }
public string sessionId { get; set; }
public string userId { get; set; }
public DialogContext(string userId, string sessionId, int maxDurationInvalidInput)
{
this.datastoreName = null;
this.entities = new List<object>();
this.vertexCandidates = null;
this.status = DialogStatus.PENDING;
this.startVertexName = null;
this.currentDurationTime = maxDurationInvalidInput;
this.currentSlotSeqNum = 0;
this.savedAttributes = new Dictionary<string, AttributePair>();
this.question = null;
this.userId = userId;
this.sessionId = sessionId;
this.scenarioName = null;
}
}
}

View File

@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System.Collections.Generic;
namespace SmartKG.Common.Data
{
public class DialogSlot
{
public string id { get; set; }
public string kgKey { get; set; }
public string question { get; set; }
public List<OptionItem> items { get; set; }
public List<string> answerValues { get; set; }
public string correspondingAttribute { get; set; }
}
}

View File

@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using MongoDB.Bson.Serialization.Attributes;
using System.Collections.Generic;
namespace SmartKG.Common.Data.KG
{
[BsonIgnoreExtraElements]
public class Edge
{
public List<string> scenarios { get; set; }
public string relationType { get; set; }
public string headVertexId { get; set; }
public string tailVertexId { get; set; }
}
}

View File

@ -0,0 +1,59 @@

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace SmartKG.Common.Data.KG
{
public class RelationLink
{
public string relationType { get; set; }
public string scenarioName { get; set; }
public RelationLink(string relationType, string scenarioName)
{
if (string.IsNullOrWhiteSpace(relationType))
{
this.relationType = "ALL";
}
else
{
this.relationType = relationType;
}
if (string.IsNullOrWhiteSpace(scenarioName))
{
this.scenarioName = "ALL";
}
else
{
this.scenarioName = scenarioName;
}
}
public bool Equals(RelationLink other)
{
if (this.relationType == other.relationType && this.scenarioName == other.scenarioName)
{
return true;
}
return false;
}
public bool IsCompatible(RelationLink other)
{
if (this.relationType != "ALL" && other.relationType != "ALL" && this.relationType != other.relationType)
{
return false;
}
if (this.scenarioName != "ALL" && other.scenarioName != "ALL" && this.scenarioName != other.scenarioName)
{
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,73 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System.Collections.Generic;
namespace SmartKG.Common.Data.KG
{
public class Vertex
{
public string id { get; set; }
public string name { get; set; }
public string label { get; set; }
public List<string> scenarios { get; set; }
public string nodeType { get; set; }
public string leadSentence { get; set; }
public List<VertexProperty> properties { get; set; }
public bool isRoot()
{
if (nodeType == "ROOT")
return true;
else
return false;
}
public bool isLeaf()
{
if (nodeType == "LEAF")
return true;
else
return false;
}
public string GetContent()
{
string result = this.name + "\n";
foreach(VertexProperty p in this.properties)
{
result += p.name + ": " + p.value + "\n";
}
return result;
}
public string GetName()
{
return this.name;
}
public string GetPropertyValue(string name)
{
if (this.properties == null || this.properties.Count == 0)
return null;
foreach (VertexProperty p in this.properties)
{
string value = p.GetValue(name);
if (!string.IsNullOrWhiteSpace(value))
{
return value;
}
}
return null;
}
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace SmartKG.Common.Data.KG
{
public class VertexProperty
{
public string name { get; set; }
public string value { get; set; }
public string GetValue(string name)
{
if (!string.IsNullOrWhiteSpace(this.name) && !string.IsNullOrWhiteSpace(name) && this.name == name)
{
return this.value;
}
return null;
}
}
}

View File

@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace SmartKG.Common.Data.LU
{
public class AttributePair
{
public string attributeName { get; set; }
public string attributeValue { get; set; }
public AttributePair(string name, string value)
{
this.attributeName = name;
this.attributeValue = value;
}
}
}

View File

@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace SmartKG.Common.Data.LU
{
public class EntityAttributeData
{
public string id { get; set; }
public string intentName { get; set; }
public string entityValue { get; set; }
public string entityType { get; set; }
public string attributeName { get; set; }
public string attributeValue { get; set; }
}
}

View File

@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace SmartKG.Common.Data.LU
{
public class EntityData
{
public string id { get; set; }
public string intentName { get; set; }
public string similarWord { get; set; }
public string entityValue { get; set; }
public string entityType { get; set; }
}
}

View File

@ -0,0 +1,81 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace SmartKG.Common.Data.LU
{
public class NLUEntity
{
private string type { get; set; }
private string value { get; set; }
public NLUEntity(string value, string type)
{
this.type = type;
this.value = value;
}
public string GetEntityValue()
{
return this.value;
}
public string GetEntityType()
{
return this.type;
}
public static string GenerateIdentity(string value, string type)
{
string identity = "";
if (type != null)
{
identity += type + "_";
}
if (value != null)
{
identity += value;
}
if (identity == "")
{
return null;
}
else
{
return identity;
}
}
public string GetIdentity()
{
string identity = "";
if (this.type != null)
{
identity += this.type + "_";
}
if (this.value != null)
{
identity += this.value;
}
if (identity == "")
{
return null;
}
else
{
return identity;
}
}
public NLUEntity Clone()
{
NLUEntity newOne = new NLUEntity( this.value, this.type);
return newOne;
}
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
namespace SmartKG.Common.Data.LU
{
public enum IntentRuleType
{
NEGATIVE, POSITIVE
}
public class NLUIntentRule
{
public string id { get; set; }
public string intentName { get; set; }
public IntentRuleType type { get; set; }
public List<String> ruleSecs { get; set; }
}
}

View File

@ -0,0 +1,137 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Newtonsoft.Json;
using System.Collections.Generic;
using System.ComponentModel;
namespace SmartKG.Common.Data.LU
{
public enum NLUResultType
{
[Description("Not Completed")]
NORMAL, NUMBER, QUITDIALOG, UNKNOWN, NOTEXIST
}
public class NLUResult
{
private NLUResultType type;
private string intent = null;
private List<NLUEntity> entities = null;
private List<AttributePair> attributes = null;
private HashSet<string> relationTypeSet = null;
private int option = -1;
public NLUResult(int option)
{
this.type = NLUResultType.NUMBER;
this.option = option;
}
public NLUResult(NLUResultType type)
{
this.type = type;
if (type == NLUResultType.QUITDIALOG)
{
this.option = 0;
}
}
public NLUResult(string intent)
{
this.type = NLUResultType.NORMAL;
this.intent = intent;
this.entities = new List<NLUEntity>();
this.attributes = new List<AttributePair>();
}
public NLUResult(string intent, List<NLUEntity> entities, List<AttributePair> attributes, HashSet<string> relationTypeSet)
{
this.type = NLUResultType.NORMAL;
this.intent = intent;
this.entities = entities;
if (attributes != null)
{
this.attributes = attributes;
}
if (relationTypeSet.Count > 0)
{
this.relationTypeSet = relationTypeSet;
}
}
public string GetIntent()
{
return this.intent;
}
public List<NLUEntity> GetEntities()
{
return this.entities;
}
public List<AttributePair> GetAttributes()
{
return this.attributes;
}
public HashSet<string> GetRelationTypeSet()
{
return relationTypeSet;
}
public int GetOption()
{
return this.option;
}
public new NLUResultType GetType()
{
return this.type;
}
override
public string ToString()
{
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("type", this.type.ToString());
if (!string.IsNullOrWhiteSpace(this.intent))
{
dict.Add("intent", this.intent);
}
if (entities != null && entities.Count > 0)
{
string entitiestr = "";
foreach (NLUEntity e in entities)
{
entitiestr += e.GetEntityType() + ":" + e.GetEntityValue();
entitiestr += ", ";
}
dict.Add("entities", entitiestr);
}
if (attributes != null && attributes.Count > 0)
{
string attrStr = "";
foreach(AttributePair attr in attributes)
{
attrStr += attr.attributeName + ": " + attr.attributeValue;
attrStr += ", ";
}
dict.Add("attributes", attrStr);
}
string result = JsonConvert.SerializeObject(dict);
return result;
}
}
}

View File

@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using SmartKG.Common.Data.KG;
namespace SmartKG.Common.Data
{
public class OptionItem
{
public int seqNo { get; set; }
public Vertex vertex { get; set; }
public string relationType { get; set; }
}
}

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SmartKG.Common.Data
{
public enum PersistanceType
{
File, MongoDB
}
}

View File

@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using SmartKG.Common.Data.KG;
using System.Collections.Generic;
namespace SmartKG.Common.Data
{
public enum VertexSortOrderType
{
ASC=0, DESC=1
}
public class SortSetting
{
public string attributeName { get; set; }
public VertexSortOrderType orderType { get; set; }
}
public class ScenarioSetting
{
public string scenarioName { get; set; }
public SortSetting sortSetting { get; set; }
public int maxOptions { get; set; }
public List<DialogSlot> slots { get; set; }
public Vertex root { get; set; }
public ScenarioSetting(string scenarioName, Vertex root)
{
this.scenarioName = scenarioName;
this.root = root;
this.sortSetting = null;
this.maxOptions = -1;
this.slots = null;
}
}
}

View File

@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using MongoDB.Bson.Serialization.Attributes;
using System.Collections.Generic;
namespace SmartKG.Common.Data.Visulization
{
[BsonIgnoreExtraElements]
public class VisulizationConfig
{
public string scenario { get; set; }
public List<ColorConfig> labelsOfVertexes { get; set; }
public List<ColorConfig> relationTypesOfEdges { get; set; }
}
[BsonIgnoreExtraElements]
public class ColorConfig
{
public string itemLabel { get; set; }
public string color { get; set; }
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace SmartKG.Common.Data.Visulization
{
public class VisulizedEdge
{
public string value { get; set; }
public string sourceId { get; set; }
public string targetId { get; set; }
}
}

View File

@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace SmartKG.Common.Data.Visulization
{
public class VisulizedVertex
{
public string id { get; set; }
public string name { get; set; }
public string displayName { get; set; }
public string label { get; set; }
}
}

View File

@ -0,0 +1,159 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Microsoft.Extensions.Configuration;
using Serilog;
using SmartKG.Common.Data;
using SmartKG.Common.Data.Configuration;
using SmartKG.Common.Data.KG;
using SmartKG.Common.Data.LU;
using SmartKG.Common.Data.Visulization;
using SmartKG.Common.DataPersistance;
using SmartKG.Common.DataStoreMgmt;
using SmartKG.Common.Logger;
using SmartKG.Common.Parser.DataPersistance;
using System;
using System.Collections.Generic;
namespace SmartKG.Common.DataPersistence
{
public class DataLoader
{
private ILogger log;
private IDataAccessor dataAccessor;
private PersistanceType persistanceType;
private FileUploadConfig uploadConfig;
private FilePathConfig filePathConfig = null;
private KGDisplayConfig kgDisplayConfig;
public DataLoader(IConfiguration config)
{
this.log = Log.Logger.ForContext<DataLoader>();
uploadConfig = config.GetSection("FileUploadConfig").Get<FileUploadConfig>();
persistanceType = (PersistanceType)Enum.Parse(typeof(PersistanceType), config.GetSection("PersistanceType").Value, true);
if (persistanceType == PersistanceType.File)
{
this.filePathConfig = config.GetSection("FileDataPath").Get<FilePathConfig>();
this.dataAccessor = new FileDataAccessor(filePathConfig.RootPath);
}
else
{
string connectionString = config.GetConnectionString("MongoDbConnection");
string mgmtDBName = config.GetConnectionString("DataStoreMgmtDatabaseName");
this.dataAccessor = new MongoDataAccessor(connectionString, mgmtDBName);
}
kgDisplayConfig = config.GetSection("KGDisplayConfig").Get<KGDisplayConfig>();
}
public List<DataStoreFrame> Load()
{
List<string> datastoreNames = dataAccessor.GetDataStoreList();
List<DataStoreFrame> datastores = new List<DataStoreFrame>();
foreach (string dsName in datastoreNames)
{
DataStoreFrame dsFrame = this.LoadDataStore(dsName);
if (dsFrame != null)
{
datastores.Add(dsFrame);
}
}
return datastores;
}
public DataStoreFrame LoadDataStore(string dsName)
{
List<Vertex> vList = null;
List<Edge> eList = null;
List<VisulizationConfig> vcList = null;
List<NLUIntentRule> iList = null;
List<EntityData> enList = null;
List<EntityAttributeData> eaList = null;
(vList, eList, vcList, iList, enList, eaList) = this.dataAccessor.Load(dsName);
if (vcList == null || vList == null || eList == null)
{
log.Here().Warning("No KG Data loaded from persistence");
return null;
}
DataPersistanceKGParser kgParser = new DataPersistanceKGParser();
KnowledgeGraphDataFrame kgDF = kgParser.ParseKG(vList, eList);
KGConfigFrame kgConfigFrame = kgParser.ParseKGConfig(vcList);
log.Information("Knowledge Graph is parsed.");
Console.WriteLine("Knowledge Graph is parsed.");
NLUDataFrame nluDF = null;
if (iList == null || enList == null)
{
log.Here().Warning("No NLU Data loaded from persistence");
}
else
{
DataPersistanceNLUParser nluParser = new DataPersistanceNLUParser();
nluDF = nluParser.Parse(iList, enList, eaList);
log.Information("NLU materials is parsed.");
Console.WriteLine("NLU materials is parsed.");
}
DataStoreFrame dsFrame = new DataStoreFrame(dsName, kgDF, kgConfigFrame, nluDF);
return dsFrame;
}
public bool UpdateColorConfig(string user, string datastoreName, string scenarioName, List<ColorConfig> colorConfigs)
{
return this.dataAccessor.UpdateColorConfig(user, datastoreName, scenarioName, colorConfigs);
}
public List<string> GetDataStoreList()
{
return this.dataAccessor.GetDataStoreList();
}
public bool CreateDataStore(string user, string datastoreName)
{
return this.dataAccessor.AddDataStore(user, datastoreName);
}
public bool DeleteDataStore(string user, string datastoreName)
{
return this.dataAccessor.DeleteDataStore(user, datastoreName);
}
public PersistanceType GetPersistanceType()
{
return this.persistanceType;
}
public FileUploadConfig GetUploadConfig()
{
return this.uploadConfig;
}
public FilePathConfig GetFilePathConfig()
{
return this.filePathConfig;
}
public int GetMaxDisplayedEntityNumber()
{
return this.kgDisplayConfig.MaxEntityNumOfScenarioToDisplay;
}
}
}

View File

@ -0,0 +1,271 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Newtonsoft.Json;
using Serilog;
using SmartKG.Common.Data.KG;
using SmartKG.Common.Data.LU;
using SmartKG.Common.Data.Visulization;
using SmartKG.Common.DataPersistence;
using SmartKG.Common.Importer;
using SmartKG.Common.Logger;
using System;
using System.Collections.Generic;
using System.IO;
namespace SmartKG.Common.DataPersistance
{
public class FileDataAccessor : IDataAccessor
{
private ILogger log;
private string rootPath;
public FileDataAccessor(string rootPath)
{
this.rootPath = rootPath;
this.log = Log.Logger.ForContext<FileDataAccessor>();
}
public (List<Vertex>, List<Edge>) LoadKG(string dsName)
{
if (string.IsNullOrWhiteSpace(dsName))
{
log.Here().Warning("The datastore: " + dsName + " doesn't exist.");
return (null, null);
}
string kgPath = this.rootPath + Path.DirectorySeparatorChar + dsName + Path.DirectorySeparatorChar + "KG" + Path.DirectorySeparatorChar;
if (string.IsNullOrWhiteSpace(kgPath) || !Directory.Exists(kgPath))
{
log.Here().Warning("The path of KGFilePath: " + kgPath + " doesn't exist.");
return (null, null);
}
log.Here().Information("KGFilePath: " + kgPath);
KGDataImporter importer = new KGDataImporter(kgPath);
List<Vertex> vList = importer.ParseKGVertexes();
List<Edge> eList = importer.ParseKGEdges();
log.Here().Information("KG data has been parsed from Files.");
return (vList, eList);
}
public List<VisulizationConfig> LoadConfig(string dsName)
{
if (string.IsNullOrWhiteSpace(dsName))
{
log.Here().Warning("The datastore: " + dsName + " doesn't exist.");
return null;
}
string vcDir = this.rootPath + Path.DirectorySeparatorChar + dsName + Path.DirectorySeparatorChar + "Visulization" + Path.DirectorySeparatorChar;
if (string.IsNullOrWhiteSpace(vcDir) || !Directory.Exists(vcDir))
{
log.Here().Warning("The path of VCFilePath: " + vcDir + " doesn't exist.");
return null;
}
VisuliaztionImporter vImporter = new VisuliaztionImporter(vcDir);
List<VisulizationConfig> vcList = vImporter.GetVisuliaztionConfigs();
log.Here().Information("Visulization Config data has been parsed from Files.");
return vcList;
}
public ( List<NLUIntentRule>, List<EntityData>, List<EntityAttributeData> ) LoadNLU(string dsName)
{
if (string.IsNullOrWhiteSpace(dsName))
{
log.Here().Warning("The datastore: " + dsName + " doesn't exist.");
return (null, null, null);
}
string nluPath = this.rootPath + Path.DirectorySeparatorChar + dsName + Path.DirectorySeparatorChar + "NLU" + Path.DirectorySeparatorChar;
if (string.IsNullOrWhiteSpace(nluPath) || !Directory.Exists(nluPath))
{
log.Here().Warning("The path of NLUFilePath: " + nluPath + " doesn't exist.");
return (null, null, null);
}
log.Here().Information("NLUFilePath: " + nluPath);
NLUDataImporter importer = new NLUDataImporter(nluPath);
List<NLUIntentRule> iList = importer.ParseIntentRules();
List<EntityData> eList = importer.ParseEntityData();
List<EntityAttributeData> eaList = importer.ParseEntityAttributeData();
return (iList, eList, eaList);
}
public (List<Vertex>, List<Edge>, List<VisulizationConfig>, List<NLUIntentRule>, List<EntityData>, List<EntityAttributeData>) Load(string dsName)
{
(var vList, var eList) = LoadKG(dsName);
var vcList = this.LoadConfig(dsName);
(var iList, var enList, var eaList) = this.LoadNLU(dsName);
return (vList, eList, vcList, iList, enList, eaList);
}
public List<string> GetDataStoreList()
{
List<string> list = new List<string>();
string[] directories = Directory.GetDirectories(rootPath);
foreach(string dir in directories)
{
string subDir = dir.Replace(rootPath, "");
subDir = subDir.Replace(Path.DirectorySeparatorChar.ToString(), "");
list.Add(subDir);
}
return list;
}
public bool AddDataStore(string user, string datastoreName)
{
string targetDir = this.rootPath + Path.DirectorySeparatorChar + datastoreName;
if (Directory.Exists(targetDir))
{
return false;
}
else
{
Directory.CreateDirectory(targetDir);
string real_targetDir = this.rootPath + Path.DirectorySeparatorChar + user + Path.DirectorySeparatorChar + datastoreName;
Directory.CreateDirectory(real_targetDir);
return true;
}
}
public bool DeleteDataStore(string user, string datastoreName)
{
string targetDir = this.rootPath + Path.DirectorySeparatorChar + datastoreName;
if (!Directory.Exists(targetDir))
{
return false;
}
else
{
string real_targetDir = this.rootPath + Path.DirectorySeparatorChar + user + Path.DirectorySeparatorChar + datastoreName;
if (!Directory.Exists(real_targetDir))
return false;
else
return DeleteDir(targetDir);
}
}
private bool DeleteDir(string targetDir)
{
System.IO.DirectoryInfo di = new DirectoryInfo(targetDir);
try
{
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in di.GetDirectories())
{
dir.Delete(true);
}
}
catch(Exception e)
{
log.Error(e.Message);
return false;
}
Directory.Delete(targetDir);
return true;
}
public bool UpdateColorConfig(string user, string dsName, string scenarioName, List<ColorConfig> colorConfigs)
{
if (string.IsNullOrWhiteSpace(dsName))
{
log.Here().Error("Error: The datastore: " + dsName + " doesn't exist.");
return false;
}
if (string.IsNullOrWhiteSpace(scenarioName))
{
log.Here().Error("Error: The scenario: " + scenarioName + " doesn't exist.");
return false;
}
string vcDir = this.rootPath + Path.DirectorySeparatorChar + dsName + Path.DirectorySeparatorChar ;
if (string.IsNullOrWhiteSpace(vcDir) || !Directory.Exists(vcDir))
{
log.Here().Warning("The path of VCFilePath: " + vcDir + " doesn't exist.");
return false;
}
string vcPath = vcDir + "Visulization" + Path.DirectorySeparatorChar + "VisulizationConfig_" + scenarioName + ".json";
//VisuliaztionImporter vImporter = new VisuliaztionImporter(vcPath);
List<VisulizationConfig> vcList = new List<VisulizationConfig>();
if (File.Exists(vcPath))
{
string json = System.IO.File.ReadAllText(vcPath);
vcList = JsonConvert.DeserializeObject<List<VisulizationConfig>>(json);
}
bool replaced = false;
foreach(VisulizationConfig config in vcList)
{
if (string.IsNullOrWhiteSpace(config.scenario) || config.scenario != scenarioName)
{
continue;
}
else
{
config.labelsOfVertexes = colorConfigs;
replaced = true;
break;
}
}
if (!replaced)
{
VisulizationConfig vc = new VisulizationConfig();
vc.scenario = scenarioName;
vc.labelsOfVertexes = colorConfigs;
vcList.Add(vc);
}
using (StreamWriter file = File.CreateText(vcPath))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, vcList);
}
log.Here().Information("Visulization Config data has been parsed from Files.");
return true;
}
}
}

View File

@ -0,0 +1,26 @@
using SmartKG.Common.Data.KG;
using SmartKG.Common.Data.LU;
using SmartKG.Common.Data.Visulization;
using System.Collections.Generic;
namespace SmartKG.Common.DataPersistence
{
public interface IDataAccessor
{
(List<Vertex>, List<Edge>) LoadKG(string datastoreName);
List<VisulizationConfig> LoadConfig(string datastoreName);
(List<NLUIntentRule>, List<EntityData>, List<EntityAttributeData>) LoadNLU(string datastoreName);
(List<Vertex>, List<Edge>, List<VisulizationConfig>, List<NLUIntentRule>, List<EntityData>, List<EntityAttributeData>) Load(string location);
List<string> GetDataStoreList();
bool AddDataStore(string user, string dsName);
bool DeleteDataStore(string user, string dsName);
bool UpdateColorConfig(string user, string dsName, string scenarioName, List<ColorConfig> colorConfigs);
}
}

View File

@ -0,0 +1,265 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using MongoDB.Bson;
using MongoDB.Driver;
using Serilog;
using SmartKG.Common.Data;
using SmartKG.Common.Data.KG;
using SmartKG.Common.Data.LU;
using SmartKG.Common.Data.Visulization;
using SmartKG.Common.DataPersistence;
using SmartKG.Common.Logger;
using System;
using System.Collections.Generic;
namespace SmartKG.Common.DataPersistance
{
public class MongoDataAccessor : IDataAccessor
{
private ILogger log;
private MongoClient client;
private string mgmtDatabaseName;
private string connectionString;
public MongoDataAccessor(string connectionString, string mgmtDatabaseName)
{
this.log = Log.Logger.ForContext<MongoDataAccessor>();
this.connectionString = connectionString;
this.client = new MongoClient(new MongoUrl(this.connectionString));
this.mgmtDatabaseName = mgmtDatabaseName;
}
public (List<Vertex>, List<Edge>) LoadKG(string dbName)
{
if (string.IsNullOrWhiteSpace(dbName))
{
log.Here().Warning("The database: " + dbName + " doesn't exist.");
return (null, null);
}
try
{
BsonDocument allFilter = new BsonDocument();
IMongoDatabase db = this.client.GetDatabase(dbName);
Console.WriteLine("Database Name: " + dbName);
IMongoCollection<Vertex> vCollection = db.GetCollection<Vertex>("Vertexes");
List<Vertex> vList = vCollection.Find(allFilter).ToList();
IMongoCollection<Edge> eCollection = db.GetCollection<Edge>("Edges");
List<Edge> eList = eCollection.Find(allFilter).ToList();
log.Here().Information("KG data has been parsed from MongoDB.");
return (vList, eList);
}
catch (Exception e)
{
log.Here().Warning("Fail to parse KG data.\n" + e.Message);
return (null, null);
}
}
public List<VisulizationConfig> LoadConfig(string dbName)
{
if (string.IsNullOrWhiteSpace(dbName))
{
log.Here().Warning("The database: " + dbName + " doesn't exist.");
return null;
}
try
{
IMongoDatabase db = this.client.GetDatabase(dbName);
IMongoCollection<VisulizationConfig> vcCollection = db.GetCollection<VisulizationConfig>("VisulizationConfigs");
BsonDocument allFilter = new BsonDocument();
List<VisulizationConfig> vcList = vcCollection.Find(allFilter).ToList();
log.Here().Information("Visulization Config data has been parsed from MongoDB.");
return vcList;
}
catch (Exception e)
{
log.Here().Warning("Fail to parse Visulization Config data.\n" + e.Message);
return null;
}
}
public (List<NLUIntentRule>, List<EntityData>, List<EntityAttributeData>) LoadNLU(string dbName)
{
if (string.IsNullOrWhiteSpace(dbName))
{
log.Here().Warning("The database: " + dbName + " doesn't exist.");
return (null, null, null);
}
try
{
BsonDocument allFilter = new BsonDocument();
IMongoDatabase db = client.GetDatabase(dbName);
IMongoCollection<NLUIntentRule> iCollection = db.GetCollection<NLUIntentRule>("IntentRules");
List<NLUIntentRule> iList = iCollection.Find(allFilter).ToList();
IMongoCollection<EntityData> eCollection = db.GetCollection<EntityData>("Entities");
List<EntityData> eList = eCollection.Find(allFilter).ToList();
IMongoCollection<EntityAttributeData> eaCollection = db.GetCollection<EntityAttributeData>("EntityAttributes");
List<EntityAttributeData> eaList = eaCollection.Find(allFilter).ToList();
log.Here().Information("NLU Data has been parsed from MongoDB.");
if (iList != null && iList.Count == 0)
iList = null;
if (eList != null && eList.Count == 0)
eList = null;
if (eaList != null && eaList.Count == 0)
eaList = null;
return (iList, eList, eaList);
}
catch (Exception e)
{
log.Here().Warning("Fail to parse NLU data.\n" + e.Message);
return (null, null, null);
}
}
public (List<Vertex>, List<Edge>, List<VisulizationConfig>, List<NLUIntentRule>, List<EntityData>, List<EntityAttributeData>) Load(string dbName)
{
(var vList, var eList) = this.LoadKG(dbName);
var vcList = this.LoadConfig(dbName);
(var iList, var enList, var eaList) = this.LoadNLU(dbName);
return (vList, eList, vcList, iList, enList, eaList);
}
public List<string> GetDataStoreList()
{
BsonDocument allFilter = new BsonDocument();
IMongoDatabase db = client.GetDatabase(this.mgmtDatabaseName);
IMongoCollection<DatastoreItem> collection = db.GetCollection<DatastoreItem>("DataStores");
List<DatastoreItem> list = collection.Find(allFilter).ToList();
List<string> result = new List<string>();
foreach(DatastoreItem item in list)
{
result.Add(item.name);
}
return result;
}
private bool IsDataStoreExist(string datastoreName)
{
IMongoDatabase db = client.GetDatabase(this.mgmtDatabaseName);
IMongoCollection<DatastoreItem> collection = db.GetCollection<DatastoreItem>("DataStores");
var searchFilter = Builders<DatastoreItem>.Filter.Eq("name", datastoreName);
var results = collection.Find(searchFilter).ToList();
if (results.Count > 0)
return true;
else
return false;
}
public bool AddDataStore(string user, string datastoreName)
{
if (IsDataStoreExist(datastoreName))
return false;
DatastoreItem item = new DatastoreItem();
item.name = datastoreName;
item.creator = user;
IMongoDatabase db = client.GetDatabase(this.mgmtDatabaseName);
IMongoCollection<DatastoreItem> collection = db.GetCollection<DatastoreItem>("DataStores");
collection.InsertOne(item);
return true;
}
private bool IsDataStoreCreatedByUser(string user, string datastoreName)
{
if (!IsDataStoreExist(datastoreName))
return false;
IMongoDatabase db = client.GetDatabase(this.mgmtDatabaseName);
IMongoCollection<DatastoreItem> collection = db.GetCollection<DatastoreItem>("DataStores");
var deleteFilter = Builders<DatastoreItem>.Filter.Eq("name", datastoreName);
var results = collection.Find(deleteFilter).ToList();
if (results.Count == 0)
return false;
if (string.IsNullOrWhiteSpace(user))
return true;
if (string.IsNullOrWhiteSpace(results[0].creator))
return true;
if (results[0].creator != user)
return false;
else
return true;
}
public bool DeleteDataStore(string user, string datastoreName)
{
if (!IsDataStoreCreatedByUser(user, datastoreName))
return false;
var deleteFilter = Builders<DatastoreItem>.Filter.Eq("name", datastoreName);
IMongoDatabase db = client.GetDatabase(this.mgmtDatabaseName);
IMongoCollection<DatastoreItem> collection = db.GetCollection<DatastoreItem>("DataStores");
collection.DeleteOne(deleteFilter);
client.DropDatabase(datastoreName);
return true;
}
public bool UpdateColorConfig(string user, string dsName, string scenarioName, List<ColorConfig> colorConfigs)
{
if (!IsDataStoreExist(dsName))
return false;
IMongoDatabase db = client.GetDatabase(dsName);
IMongoCollection<VisulizationConfig> collection = db.GetCollection<VisulizationConfig>("VisulizationConfigs");
var deleteFilter = Builders<VisulizationConfig>.Filter.Eq("scenario", scenarioName);
collection.DeleteOne(deleteFilter);
VisulizationConfig vConfig = new VisulizationConfig();
vConfig.scenario = scenarioName;
vConfig.labelsOfVertexes = colorConfigs;
collection.InsertOne(vConfig);
return true;
}
}
}

View File

@ -0,0 +1,350 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Newtonsoft.Json;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using SmartKG.Common.Logger;
using SmartKG.Common.Data.KG;
using SmartKG.Common.Data.LU;
using SmartKG.Common.Data;
namespace SmartKG.Common.DataStoreMgmt
{
public class DataStoreFrame
{
private string datastoreName;
private KnowledgeGraphDataFrame kgDF;
private KGConfigFrame kgConfigFrame;
private NLUDataFrame nluDF;
private ILogger log;
public DataStoreFrame(string datastoreName, KnowledgeGraphDataFrame kgDF, KGConfigFrame kgConfigFrame, NLUDataFrame nluDF)
{
log = Log.Logger.ForContext<DataStoreFrame>();
this.datastoreName = datastoreName;
this.kgDF = kgDF; //new KnowledgeGraphDataFrame();
this.kgConfigFrame = kgConfigFrame;
this.nluDF = nluDF; // new NLUDataFrame();
}
public string GetName()
{
return this.datastoreName;
}
public KnowledgeGraphDataFrame GetKG()
{
return this.kgDF;
}
public KGConfigFrame GetKGConfig()
{
return this.kgConfigFrame;
}
public NLUDataFrame GetNLU()
{
return this.nluDF;
}
public void LogInformation(ILogger log, string title, string content)
{
log.Information(title + " " + content);
}
public void LogError(ILogger log, Exception e)
{
log.Error(e.Message, e);
}
public int GetMaxOptions(string scenarioName)
{
return this.nluDF.GetSetting(scenarioName).maxOptions;
}
public SortSetting GetSortSetting(string scenarioName)
{
return this.nluDF.GetSetting(scenarioName).sortSetting;
}
public List<DialogSlot> GetConfiguredSlots(string scenarioName)
{
if (this.nluDF.GetSetting(scenarioName) != null)
return this.nluDF.GetSetting(scenarioName).slots;
else
return null;
}
public List<Vertex> SearchGraphByLabel(string label, string scenarioName, List<AttributePair> attributes)
{
if (string.IsNullOrWhiteSpace(label))
{
return null;
}
else
{
List<Vertex> vertexes = kgDF.GetVertexByLabel(label);
return Filter(vertexes, scenarioName, attributes);
}
}
public Vertex SearchGraph(string startVertexName, string scenarioName, List<AttributePair> attributes)
{
if (string.IsNullOrWhiteSpace(startVertexName) && string.IsNullOrWhiteSpace(scenarioName))
{
return null;
}
else if (string.IsNullOrWhiteSpace(startVertexName) && !string.IsNullOrWhiteSpace(scenarioName))
{
Vertex root = nluDF.GetRoot(scenarioName);
if (root != null)
{
startVertexName = root.name;
}
else
{
return null;
}
}
List<Vertex> vertexes = kgDF.GetVertexByName(startVertexName);
List<Vertex> results = Filter(vertexes, scenarioName, attributes);
if (results != null && results.Count > 0)
{
return results[0];
}
else
{
return null;
}
}
private List<Vertex> Filter(List<Vertex> vertexes, string scenarioName, List<AttributePair> attributes)
{
if (vertexes != null)
{
List<Vertex> results = new List<Vertex>();
foreach (Vertex vertex in vertexes)
{
if (!string.IsNullOrWhiteSpace(scenarioName) && (vertex.scenarios != null && !vertex.scenarios.Contains(scenarioName)))
{
continue;
}
if (IsSelected(vertex, attributes))
{
results.Add(vertex);
}
}
if (results.Count > 0)
{
return results;
}
else
{
return null;
}
}
else
{
LogInformation(log.Here(), "Vertexes", "doesn't filtered with attributes: " + JsonConvert.SerializeObject(attributes));
return null;
}
}
public Dictionary<string, List<Vertex>> FilterGraph(string startVertexName, string scenarioName, HashSet<string> relationTypeSet, List<AttributePair> attributes)
{
if (string.IsNullOrWhiteSpace(startVertexName) && string.IsNullOrWhiteSpace(scenarioName))
{
return null;
}
else if (string.IsNullOrWhiteSpace(startVertexName) && !string.IsNullOrWhiteSpace(scenarioName))
{
Vertex root = nluDF.GetRoot(scenarioName);
if (root != null)
{
startVertexName = root.name;
}
else
{
return null;
}
}
Dictionary<string, List<Vertex>> results = new Dictionary<string, List<Vertex>>();
Vertex startVertex = SearchGraph(startVertexName, scenarioName, attributes);
if (startVertex == null)
{
LogInformation(log.Here(), startVertexName, "doesn't exist");
return null;
}
List<Vertex> tobeProcessedVertexes = new List<Vertex>();
tobeProcessedVertexes.Add(startVertex);
int index = 0;
while (index < tobeProcessedVertexes.Count())
{
Vertex vertex = tobeProcessedVertexes[index];
Dictionary<string, HashSet<string>> childrenIds = new Dictionary<string, HashSet<string>>();
if (relationTypeSet == null)
{
childrenIds = kgDF.GetChildrenIds(vertex.id, null, scenarioName);
}
else
{
foreach (string relationType in relationTypeSet)
{
Dictionary<string, HashSet<string>> cIds = kgDF.GetChildrenIds(vertex.id, relationType, scenarioName);
if (cIds != null && cIds.Count > 0)
{
childrenIds.Add(relationType, cIds[relationType]);
}
}
}
if (childrenIds == null)
continue;
foreach (string relationType in childrenIds.Keys)
{
foreach (string childId in childrenIds[relationType])
{
Vertex child = kgDF.GetVertexById(childId);
if (child != null)
{
if (child.isLeaf())
{
if (IsSelected(child, attributes))
{
if (results.ContainsKey(relationType))
{
results[relationType].Add(child);
}
else
{
results.Add(relationType, new List<Vertex> { vertex });
}
}
}
else
{
tobeProcessedVertexes.Add(child);
}
}
}
}
index += 1;
}
return results;
}
private bool IsSelected(Vertex vertex, List<AttributePair> attributes)
{
bool isSelected = true;
if (attributes == null || attributes.Count() == 0)
return true;
foreach (AttributePair attribute in attributes)
{
string attributeValue = attribute.attributeValue;
try
{
string value = vertex.GetPropertyValue(attribute.attributeName);
if ((value != null) && (value != "ALL") && (attributeValue != "ALL") && (attributeValue != value))
{
isSelected = false;
break;
}
}
catch (Exception e)
{
LogError(log.Here(), e);
}
}
return isSelected;
}
public Dictionary<string, List<Vertex>> GetChildren(Vertex vertex, HashSet<string> relationTypeSet, List<AttributePair> attributes, string scenarioName)
{
if (vertex.isLeaf())
{
LogInformation(log.Here(), vertex.name, "is a leaf");
return null;
}
string id = vertex.id;
Dictionary<string, HashSet<string>> childrenIds = new Dictionary<string, HashSet<string>>();
if (relationTypeSet != null)
{
foreach (string relationType in relationTypeSet)
{
Dictionary<string, HashSet<string>> cIds = kgDF.GetChildrenIds(vertex.id, relationType, scenarioName);//allTypeChildrenIds.SelectMany(x => x.Value).ToList();
if (cIds != null && cIds.Count > 0)
{
childrenIds.Add(relationType, cIds[relationType]);
}
}
}
else
{
childrenIds = kgDF.GetChildrenIds(vertex.id, null, scenarioName);
}
if (childrenIds == null || childrenIds.Count == 0)
{
LogInformation(log.Here(), vertex.name, "has no child");
return null;
}
Dictionary<string, List<Vertex>> results = new Dictionary<string, List<Vertex>>();
foreach (string relationType in childrenIds.Keys)
{
List<Vertex> vertexes = new List<Vertex>();
foreach (string cId in childrenIds[relationType])
{
Vertex child = kgDF.GetVertexById(cId);
if (child != null && IsSelected(child, attributes))
vertexes.Add(child);
}
if (vertexes.Count > 0)
{
results.Add(relationType, vertexes);
}
}
return results;
}
}
}

View File

@ -0,0 +1,231 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Microsoft.Extensions.Configuration;
using MongoDB.Bson.Serialization.IdGenerators;
using Serilog;
using SmartKG.Common.Data;
using SmartKG.Common.Data.Configuration;
using SmartKG.Common.Data.Visulization;
using SmartKG.Common.DataPersistence;
using System;
using System.Collections.Generic;
using System.IO;
namespace SmartKG.Common.DataStoreMgmt
{
public class DataStoreManager
{
private static DataStoreManager uniqueInstance;
private Dictionary<string, DataStoreFrame> datastoreDict;
private ILogger log;
private DataLoader dataLoader;
private DataStoreManager(IConfiguration config)
{
log = Log.Logger.ForContext<DataStoreManager>();
this.datastoreDict = new Dictionary<string, DataStoreFrame>();
this.dataLoader = new DataLoader(config);
}
public static DataStoreManager initInstance(IConfiguration config)
{
if (uniqueInstance == null)
{
uniqueInstance = new DataStoreManager(config);
}
return uniqueInstance;
}
public static DataStoreManager GetInstance()
{
return uniqueInstance;
}
public bool CreateDataStore(string user, string dsName)
{
return this.dataLoader.CreateDataStore(user, dsName);
}
public bool DeleteDataStore(string user, string dsName)
{
bool success = this.dataLoader.DeleteDataStore(user, dsName);
if (success)
{
this.datastoreDict.Remove(dsName);
}
return success;
}
public List<string> GetDataStoreList()
{
return this.dataLoader.GetDataStoreList();
}
public void LoadDataStores()
{
List<DataStoreFrame> datastores = this.dataLoader.Load();
int count = 0;
foreach(DataStoreFrame dsFrame in datastores)
{
bool success;
(success, _)= this.SaveDataStoreInDict(dsFrame);
if (success)
count += 1;
}
log.Information("Totally " + count + " datastores have been loaded.");
}
public (bool, string) LoadDataStore(string dsName)
{
DataStoreFrame dsFrame = this.dataLoader.LoadDataStore(dsName);
return this.SaveDataStoreInDict(dsFrame);
}
private (bool, string) SaveDataStoreInDict(DataStoreFrame dsFrame)
{
if (dsFrame == null)
{
log.Error("Error: DataStoreFrame doesn't exist.");
return (false, "DataStoreFrame doesn't exist.");
}
string dsName = dsFrame.GetName();
if (dsFrame.GetKG().GetAllVertexes().Count == 0)
{
log.Error("Error: DataStoreFrame " + dsName + " is empty.");
return (false, "DataStoreFrame " + dsName + " is empty.");
}
if (this.datastoreDict.ContainsKey(dsName))
{
log.Warning("Warning: DataStore Name cannot be duplicated. The " + dsName + " has existed.");
this.datastoreDict[dsName] = dsFrame;
log.Information("The " + dsName + " has been reloaded.");
}
else
{
this.datastoreDict.Add(dsName, dsFrame);
log.Information("The " + dsName + " has been loaded now.");
}
return (true, "The " + dsName + " has been loaded.");
}
public DataStoreFrame GetDataStore(string dsName)
{
if (this.datastoreDict.ContainsKey(dsName))
{
return this.datastoreDict[dsName];
}
log.Error("The " + dsName + " doesn't existed.");
return null;
}
public string GetUploadedFileSaveDir()
{
FileUploadConfig uploadConfig = this.dataLoader.GetUploadConfig();
string excelDir = uploadConfig.ExcelDir;
return excelDir;
}
public PersistanceType GetPersistanceType()
{
return this.dataLoader.GetPersistanceType();
}
public string GetSavedExcelFilePath(string savedFileName)
{
FileUploadConfig uploadConfig = this.dataLoader.GetUploadConfig();
string excelDir = uploadConfig.ExcelDir;
string savedExcelFilePath = excelDir + Path.DirectorySeparatorChar + savedFileName ;
return savedExcelFilePath;
}
public (string, string) GetTargetDirPath(string datastoreName)
{
FileUploadConfig uploadConfig = this.dataLoader.GetUploadConfig();
PersistanceType persistanceType = this.dataLoader.GetPersistanceType();
FilePathConfig filePathConfig = this.dataLoader.GetFilePathConfig();
string configPath = uploadConfig.ColorConfigPath;
string targetDir = null;
if (persistanceType == PersistanceType.File && filePathConfig != null)
{
targetDir = filePathConfig.RootPath + Path.DirectorySeparatorChar + datastoreName;
}
else
{
string excelDir = uploadConfig.ExcelDir;
targetDir = excelDir + Path.DirectorySeparatorChar + DateTime.Now.ToString("MMddyyyyHHmmss");
}
return (configPath, targetDir);
}
public (FileUploadConfig, string, string) GenerateConvertDirs(string datastoreName, string savedFileName, string scenario)
{
FileUploadConfig uploadConfig = this.dataLoader.GetUploadConfig();
PersistanceType persistanceType = this.dataLoader.GetPersistanceType();
FilePathConfig filePathConfig = this.dataLoader.GetFilePathConfig();
string excelDir = uploadConfig.ExcelDir;
string pythonArgs = "--configPath \"" + uploadConfig.ColorConfigPath + "\" ";
pythonArgs += " --srcPaths ";
pythonArgs += "\"" + excelDir + Path.DirectorySeparatorChar + savedFileName + "\" ";
pythonArgs += " --scenarios ";
pythonArgs += "\"" + scenario + "\" ";
string targetDir = null;
if (persistanceType == PersistanceType.File && filePathConfig != null)
{
targetDir = filePathConfig.RootPath + Path.DirectorySeparatorChar + datastoreName;
}
else
{
targetDir = excelDir + Path.DirectorySeparatorChar + DateTime.Now.ToString("MMddyyyyHHmmss");
}
pythonArgs += " --destPath \"" + targetDir + "\" ";
return (uploadConfig, pythonArgs, targetDir);
}
public bool UpdateColorConfig(string user, string dsName, string scenarioName, List<ColorConfig> colorConfigs)
{
return this.dataLoader.UpdateColorConfig(user, dsName, scenarioName, colorConfigs);
}
public int GetMaxDisplayedEntityNumber()
{
return this.dataLoader.GetMaxDisplayedEntityNumber();
}
}
}

View File

@ -0,0 +1,94 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Serilog;
using SmartKG.Common.Data.Visulization;
using System.Collections.Generic;
namespace SmartKG.Common.DataStoreMgmt
{
public class KGConfigFrame
{
private Dictionary<string, List<ColorConfig>> vertexLabelColorMap { get; set; }
private ILogger log;
public KGConfigFrame()
{
log = Log.Logger.ForContext<KGConfigFrame>();
this.Clean();
}
public void Clean()
{
this.vertexLabelColorMap = new Dictionary<string, List<ColorConfig>>();
}
public void SetVertexLabelColorMap(Dictionary<string, List<ColorConfig>> map)
{
this.vertexLabelColorMap = map;
}
/*public Dictionary<string, List<ColorConfig>> GetVertexLabelColorMap()
{
return this.vertexLabelColorMap;
}*/
public (bool, List<ColorConfig>) GetColorConfigForScenario(string scenarioName)
{
if (this.vertexLabelColorMap == null || this.vertexLabelColorMap.Count == 0)
{
return (false, null);
}
if (string.IsNullOrWhiteSpace(scenarioName))
{
List<ColorConfig> configs = new List<ColorConfig>();
foreach (string scenario in this.vertexLabelColorMap.Keys)
{
configs.AddRange(this.vertexLabelColorMap[scenario]);
}
return (true, configs);
}
else
{
if (!this.vertexLabelColorMap.ContainsKey(scenarioName))
{
return (false, null);
}
else
{
return (true, this.vertexLabelColorMap[scenarioName]);
}
}
}
public (bool, string) UpdateVertexLabelColorMapForScenario(string scenarioName, List<ColorConfig> colorConfigs)
{
if (this.vertexLabelColorMap == null || this.vertexLabelColorMap.Count == 0)
{
return (false, "The scenario " + scenarioName + " doesn't exist.");
}
if (colorConfigs == null || colorConfigs.Count == 0)
{
return (false, "The color config of cannot be null.");
}
if (this.vertexLabelColorMap == null)
{
this.vertexLabelColorMap = new Dictionary<string, List<ColorConfig>>();
}
if (!this.vertexLabelColorMap.ContainsKey(scenarioName))
{
this.vertexLabelColorMap.Add(scenarioName, colorConfigs);
}
else
{
this.vertexLabelColorMap[scenarioName] = colorConfigs;
}
return (true, "The scenario " + scenarioName + " color configs are updated successfully.");
}
}
}

View File

@ -0,0 +1,331 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Serilog;
using SmartKG.Common.Data.KG;
using SmartKG.Common.Data.Visulization;
using System;
using System.Collections.Generic;
using System.Linq;
namespace SmartKG.Common.DataStoreMgmt
{
public class KnowledgeGraphDataFrame
{
private Dictionary<string, List<Vertex>> vertexNameCache { get; set; }
private Dictionary<string, Vertex> vertexIdCache { get; set; }
private Dictionary<string, Dictionary<RelationLink, List<string>>> outRelationDict { get; set; }
private Dictionary<string, Dictionary<RelationLink, List<string>>> inRelationDict { get; set; }
private Dictionary<string, List<Edge>> scenarioEdgesDict { get; set; }
//private Dictionary<string, List<ColorConfig>> vertexLabelColorMap { get; set; }
private List<Vertex> rootVertexes { get; set; }
private HashSet<string> scenarioNames { get; set; }
private ILogger log;
public KnowledgeGraphDataFrame()
{
log = Log.Logger.ForContext<KnowledgeGraphDataFrame>();
this.Clean();
}
public void Clean()
{
this.vertexNameCache = new Dictionary<string, List<Vertex>>();
this.vertexIdCache = new Dictionary<string, Vertex>();
this.outRelationDict = new Dictionary<string, Dictionary<RelationLink, List<string>>>();
this.inRelationDict = new Dictionary<string, Dictionary<RelationLink, List<string>>>();
this.scenarioEdgesDict = new Dictionary<string, List<Edge>>();
//this.vertexLabelColorMap = new Dictionary<string, List<ColorConfig>>();
this.rootVertexes = new List<Vertex>();
this.scenarioNames = new HashSet<string>();
}
public void SetRootVertexes(List<Vertex> roots)
{
this.rootVertexes = roots;
}
public List<Vertex> GetRootVertexes()
{
return this.rootVertexes;
}
public HashSet<string> GetScenarioNames()
{
return this.scenarioNames;
}
public void SetScenarioNames(HashSet<string> scenarios)
{
this.scenarioNames = scenarios;
}
public void SetVertexNameCache(Dictionary<string, List<Vertex>> vertexNameCache)
{
this.vertexNameCache = vertexNameCache;
}
public void SetVertexIdCache(Dictionary<string, Vertex> vertexIdCache)
{
this.vertexIdCache = vertexIdCache;
}
public void SetOutRelationDict(Dictionary<string, Dictionary<RelationLink, List<string>>> outRelationDict)
{
this.outRelationDict = outRelationDict;
}
public void SetInRelationDict(Dictionary<string, Dictionary<RelationLink, List<string>>> inRelationDict)
{
this.inRelationDict = inRelationDict;
}
public List<Vertex> GetVertexByLabel(string label)
{
if (string.IsNullOrWhiteSpace(label))
{
return null;
}
List<Vertex> results = new List<Vertex>();
foreach (List<Vertex> vertexes in this.vertexNameCache.Values)
{
foreach (Vertex vertex in vertexes)
{
if (vertex.label.Contains(label))
{
results.Add(vertex);
}
}
}
return results;
}
public List<Vertex> GetVertexByName(string vertexName)
{
if (string.IsNullOrWhiteSpace(vertexName))
{
return null;
}
if (!this.vertexNameCache.Keys.Contains(vertexName))
{
log.Information(vertexName, "doesn't exist");
return null;
}
else
{
return this.vertexNameCache[vertexName];
}
}
public List<Vertex> GetVertexByKeyword(string scenarioName, string keyword)
{
if (string.IsNullOrWhiteSpace(keyword))
{
return null;
}
List<string> vNames = this.vertexNameCache.Keys.ToList();
HashSet<string> matchedNames = new HashSet<string>();
foreach (string vName in vNames)
{
if (vName.Contains(keyword))
{
if (scenarioName != null)
{
foreach(Vertex v in this.vertexNameCache[vName])
{
if (v.scenarios.Contains(scenarioName))
{
matchedNames.Add(vName);
break;
}
}
}
else
{
matchedNames.Add(vName);
}
}
}
List<Vertex> results = new List<Vertex>();
foreach (string mV in matchedNames)
{
List<Vertex> mR = GetVertexByName(mV);
if (mR != null && mR.Count > 0)
{
results.AddRange(mR);
}
}
if (results.Count == 0)
{
return null;
}
else
{
return results;
}
}
public (bool, List<Vertex>) GetVertexesByScenarios(List<string> scenarios)
{
List<Vertex> allVertexes = this.vertexIdCache.Values.ToList();
if (scenarios == null || scenarios.Count == 0)
{
return (true, allVertexes);
}
bool isScenarioExist = false;
List<Vertex> catchedVertexes = new List<Vertex>();
foreach (Vertex vertex in allVertexes)
{
if (vertex.scenarios == null || vertex.scenarios.Count == 0)
{
continue;
}
foreach (string scenario in scenarios)
{
if (vertex.scenarios.Contains(scenario))
{
isScenarioExist = true;
catchedVertexes.Add(vertex);
break;
}
}
}
return (isScenarioExist, catchedVertexes);
}
public List<Edge> GetRelationsByScenarios(List<string> scenarios)
{
List<Edge> results = new List<Edge>();
if (scenarios == null || scenarios.Count == 0)
{
foreach (string key in this.scenarioEdgesDict.Keys)
{
results.AddRange(this.scenarioEdgesDict[key]);
}
}
else
{
foreach (string scenario in scenarios)
{
if (this.scenarioEdgesDict.ContainsKey(scenario))
{
results.AddRange(this.scenarioEdgesDict[scenario]);
}
}
}
return results;
}
public void SetScenarioEdgesDict(Dictionary<string, List<Edge>> scenarioEdgesDict)
{
this.scenarioEdgesDict = scenarioEdgesDict;
}
public List<Vertex> GetAllVertexes()
{
return this.vertexIdCache.Values.ToList();
}
public Vertex GetVertexById(string vertexId)
{
if (!this.vertexIdCache.Keys.Contains(vertexId))
{
log.Information(vertexId, "doesn't exist");
return null;
}
else
{
return this.vertexIdCache[vertexId];
}
}
public Dictionary<RelationLink, List<string>> GetChildrenLinkDict(string vertexId)
{
if (vertexId != null && this.outRelationDict.ContainsKey(vertexId))
{
return this.outRelationDict[vertexId];
}
return null;
}
public Dictionary<RelationLink, List<string>> GetParentLinkDict(string vertexId)
{
if (vertexId != null && this.inRelationDict.ContainsKey(vertexId))
{
return this.inRelationDict[vertexId];
}
return null;
}
public Dictionary<string, HashSet<string>> GetChildrenIds(string vertexId, string relationType, string scenarioName)
{
if (string.IsNullOrWhiteSpace(vertexId))
{
return null;
}
RelationLink targetLink = new RelationLink(relationType, scenarioName);
Dictionary<string, HashSet<string>> childrenIds = new Dictionary<string, HashSet<string>>();
if (outRelationDict.ContainsKey(vertexId))
{
foreach (RelationLink link in outRelationDict[vertexId].Keys)
{
if (targetLink.IsCompatible(link))
{
string linkRelationType = link.relationType;
if (!childrenIds.ContainsKey(linkRelationType))
{
HashSet<string> cIds = new HashSet<string>();
childrenIds.Add(linkRelationType, cIds);
}
List<string> conncectedIds = outRelationDict[vertexId][link];
foreach (string cid in conncectedIds)
{
childrenIds[linkRelationType].Add(cid);
}
}
}
}
return childrenIds;
}
}
}

View File

@ -0,0 +1,350 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using SmartKG.Common.Data.KG;
using SmartKG.Common.Data.LU;
using SmartKG.Common.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Serilog;
namespace SmartKG.Common.DataStoreMgmt
{
public class NLUDataFrame
{
private Dictionary<string, Dictionary<string, List<NLUEntity>>> standValueMap;
private Dictionary<string, Dictionary<string, Dictionary<string, NLUEntity>>> entityMap;
private Dictionary<string, Dictionary<string, List<AttributePair>>> attributeMap;
private List<NLUIntentRule> intentPositiveDetermineRules;
private Dictionary<string, List<NLUIntentRule>> intentNegativeDeterminRules;
private Dictionary<string, ScenarioSetting> sceanrioCache;
private ILogger log;
public NLUDataFrame()
{
log = Log.Logger.ForContext<NLUDataFrame>();
this.Clean();
}
public void Clean()
{
this.standValueMap = new Dictionary<string, Dictionary<string, List<NLUEntity>>>();
this.attributeMap = new Dictionary<string, Dictionary<string, List<AttributePair>>>();
this.entityMap = new Dictionary<string, Dictionary<string, Dictionary<string, NLUEntity>>>();
this.intentPositiveDetermineRules = new List<NLUIntentRule>();
this.intentNegativeDeterminRules = new Dictionary<string, List<NLUIntentRule>>();
this.sceanrioCache = new Dictionary<string, ScenarioSetting>();
}
public NLUEntity AddEntity(string intentName, string entityValue, string entityType)
{
Dictionary<string, Dictionary<string, NLUEntity>> typeEntities;
if (!this.entityMap.Keys.Contains(intentName))
{
typeEntities = new Dictionary<string, Dictionary<string, NLUEntity>>();
this.entityMap.Add(intentName, typeEntities);
}
typeEntities = this.entityMap[intentName];
Dictionary<string, NLUEntity> entities;
if (!typeEntities.Keys.Contains(entityType))
{
entities = new Dictionary<string, NLUEntity>();
typeEntities.Add(entityType, entities);
}
entities = typeEntities[entityType];
if (!entities.Keys.Contains(entityValue))
{
NLUEntity entity = new NLUEntity(entityValue, entityType);
entities.Add(entityValue, entity);
return entity;
}
else
{
return entities[entityValue];
}
}
public void AddSimilarWord(string intentName, string similarWord, NLUEntity entity)
{
if (!this.standValueMap.Keys.Contains(intentName))
{
Dictionary<string, List<NLUEntity>> wordToEntity = new Dictionary<string, List<NLUEntity>>();
this.standValueMap.Add(intentName, wordToEntity);
}
if (this.standValueMap[intentName].Keys.Contains(similarWord))
{
this.standValueMap[intentName][similarWord].Add(entity);
}
else
{
this.standValueMap[intentName].Add(similarWord, new List<NLUEntity>() { entity });
}
}
public void AddAttribute(string intentName, NLUEntity entity, AttributePair attribute)
{
if (!this.attributeMap.Keys.Contains(intentName))
{
Dictionary<string, List<AttributePair>> wordToAttribute = new Dictionary<string, List<AttributePair>>();
this.attributeMap.Add(intentName, wordToAttribute);
}
string key = entity.GetIdentity();
if (!this.attributeMap[intentName].Keys.Contains(key))
{
this.attributeMap[intentName].Add(key, new List<AttributePair>());
}
this.attributeMap[intentName][key].Add(attribute);
}
public List<NLUEntity> DetectEntities(string intentName, string query)
{
List<NLUEntity> resultList = new List<NLUEntity>();
if (!this.standValueMap.Keys.Contains(intentName))
{
return resultList;
}
try
{
SortedDictionary<int, List<NLUEntity>> results = new SortedDictionary<int, List<NLUEntity>>();
Dictionary<string, List<NLUEntity>> wordToEntity = this.standValueMap[intentName];
List<string> similarWords = wordToEntity.Keys.ToList<string>();
foreach (string word in similarWords)
{
string lowerWord = null;
if (word != null)
lowerWord = word.ToLower();
if (query.Contains(lowerWord))
{
int pos = query.IndexOf(lowerWord);
List<NLUEntity> entities = wordToEntity[word];
//int key = word.Length;
if (results.ContainsKey(pos))
{
results[pos].AddRange(entities.Select(item => item.Clone()).ToList());
}
else
{
results.Add(pos, entities.Select(item => item.Clone()).ToList());
}
}
}
foreach (var pair in results)//.Reverse())
{
resultList.AddRange(pair.Value);
}
}
catch (Exception e)
{
throw new Exception("Parse entities error.", e);
}
return resultList;
}
public List<AttributePair> ParseAttributes(string intentName, List<NLUEntity> entities)
{
if (entities == null || entities.Count() == 0)
return null;
try
{
List<AttributePair> pairs = new List<AttributePair>();
Dictionary<string, List<AttributePair>> map = this.attributeMap[intentName];
foreach (NLUEntity entity in entities)
{
string identity = entity.GetIdentity();
if (map.Keys.Contains(identity))
{
pairs.AddRange(map[identity]);
}
}
if (pairs.Count() > 0)
{
return pairs;
}
else
{
return null;
}
}
catch { return null; }
}
public void AddIntentRule(NLUIntentRule intentRule)
{
if (intentRule.type == IntentRuleType.POSITIVE)
this.intentPositiveDetermineRules.Add(intentRule);
else if (intentRule.type == IntentRuleType.NEGATIVE)
{
string intentName = intentRule.intentName;
if (!this.intentNegativeDeterminRules.Keys.Contains(intentName))
{
this.intentNegativeDeterminRules.Add(intentName, new List<NLUIntentRule>());
}
this.intentNegativeDeterminRules[intentName].Add(intentRule);
}
}
private bool IsMatched(List<string> ruleSecs, string query)
{
bool matched = true;
foreach (string ruleSec in ruleSecs)
{
Regex regex = new Regex(ruleSec.ToLower());
Match match = regex.Match(query);
if (!match.Success)
{
matched = false;
break;
}
}
return matched;
}
private TempData MatchPositiveRules(string query, int startIndex)
{
TempData result = new TempData();
int index = startIndex;
while (index < this.intentPositiveDetermineRules.Count())
{
NLUIntentRule rule = this.intentPositiveDetermineRules[index];
bool matched = IsMatched(rule.ruleSecs, query);
if (matched)
{
result.intentName = rule.intentName;
result.positionInPosRules = index;
return result;
}
else
{
index += 1;
}
}
return null;
}
private bool IsNegative(string query, string intentName)
{
if (!this.intentNegativeDeterminRules.Keys.Contains(intentName))
{
return false;
}
else
{
foreach (NLUIntentRule rule in this.intentNegativeDeterminRules[intentName])
{
bool matched = IsMatched(rule.ruleSecs, query);
if (matched)
{
return true;
}
}
return false;
}
}
public string DetectIntent(string query)
{
int index = 0;
while (index < this.intentPositiveDetermineRules.Count())
{
TempData temp = MatchPositiveRules(query, index);
if (temp == null)
{
index += 1;
}
else
{
if (IsNegative(query, temp.intentName))
{
index = temp.positionInPosRules + 1;
}
else
{
return temp.intentName;
}
}
}
return null;
}
public void SetSceanrioCache(Dictionary<string, ScenarioSetting> sceanrioCache)
{
this.sceanrioCache = sceanrioCache;
}
public ScenarioSetting GetSetting(string scenarioName)
{
if (!this.sceanrioCache.Keys.Contains(scenarioName))
{
return null;
}
return this.sceanrioCache[scenarioName];
}
public Vertex GetRoot(string scenarioName)
{
if (this.sceanrioCache.ContainsKey(scenarioName))
{
return this.sceanrioCache[scenarioName].root;
}
else
{
return null;
}
}
}
class TempData
{
public string intentName { get; set; }
public int positionInPosRules { get; set; }
}
}

View File

@ -0,0 +1,119 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Newtonsoft.Json;
using Serilog;
using SmartKG.Common.Data.KG;
using SmartKG.Common.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace SmartKG.Common.Importer
{
public class KGDataImporter
{
private string rootPath;
private List<string> vertexFileNames = new List<string>();
private List<string> edgeFileNames = new List<string>();
private HashSet<string> vertexIds = new HashSet<string>();
private HashSet<string> edgeIds = new HashSet<string>();
private ILogger log;
public KGDataImporter(string rootPath)
{
log = Log.Logger.ForContext<KGDataImporter>();
if (string.IsNullOrWhiteSpace(rootPath))
{
throw new Exception("Rootpath of KG files are invalid.");
}
this.rootPath = PathUtility.CompletePath(rootPath);
string[] files = Directory.GetFiles(rootPath, "*.json").Select(Path.GetFileName).ToArray();
foreach (string file in files)
{
if (file.Contains("Edge"))
{
this.edgeFileNames.Add(file);
}
else if (file.Contains("Vertex"))
{
this.vertexFileNames.Add(file);
}
}
}
public List<Edge> ParseKGEdges()
{
List<Edge> edges = new List<Edge>();
foreach(string file in this.edgeFileNames)
{
edges.AddRange(ParseKGEdges(file));
}
return edges;
}
private List<Edge> ParseKGEdges(string filename)
{
List<Edge> output = new List<Edge>();
string fileName = rootPath + filename;
string content = File.ReadAllText(fileName);
List<Edge> edges = JsonConvert.DeserializeObject<List<Edge>>(content);
foreach (Edge edge in edges)
{
output.Add(edge);
}
return output;
}
public List<Vertex> ParseKGVertexes()
{
List<Vertex> vertexes = new List<Vertex>();
foreach(string file in this.vertexFileNames)
{
vertexes.AddRange(this.ParseKGVertexes(file));
}
return vertexes;
}
private List<Vertex> ParseKGVertexes(string filename)
{
List<Vertex> output = new List<Vertex>();
string fileName = rootPath + filename;
string content = File.ReadAllText(fileName);
List<Vertex> vertexes = JsonConvert.DeserializeObject<List<Vertex>>(content);
foreach (Vertex vertex in vertexes)
{
if (vertexIds.Contains(vertex.id))
{
Console.WriteLine(vertex.id);
}
else
{
vertexIds.Add(vertex.id);
}
output.Add(vertex);
}
return output;
}
}
}

View File

@ -0,0 +1,217 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Newtonsoft.Json;
using Serilog;
using SmartKG.Common.Data.LU;
using SmartKG.Common.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace SmartKG.Common.Importer
{
public class NLUDataImporter
{
private string rootPath;
private ILogger log;
public NLUDataImporter(string rootPath)
{
log = Log.Logger.ForContext<NLUDataImporter>();
if (string.IsNullOrWhiteSpace(rootPath))
{
throw new Exception("Rootpath of NLU files are invalid.");
}
this.rootPath = PathUtility.CompletePath(rootPath);
}
public List<NLUIntentRule> ParseIntentRules()
{
List<NLUIntentRule> list = new List<NLUIntentRule>();
string[] fileNamess = Directory.GetFiles(rootPath, "intentrules*.json").Select(Path.GetFileName).ToArray();
foreach (string fileName in fileNamess)
{
string content = File.ReadAllText(this.rootPath + fileName);
list.AddRange(JsonConvert.DeserializeObject<List<NLUIntentRule>>(content));
}
/*List<string> lines = new List<string>();
foreach (string fileName in fileNamess)
{
string content = File.ReadAllText(rootPath + fileName);
lines.AddRange(content.Split('\n').ToList<string>());
}
int seqNo = 1;
foreach (string line in lines)
{
string theLine = line.Trim();
string[] tmps = theLine.Split('\t');
if (tmps.Count() != 3)
{
throw new Exception("invalid line in intentrules.tsv");
}
else
{
NLUIntentRule rule = new NLUIntentRule();
rule.intentName = tmps[0].Trim();
string typeStr = tmps[1].Trim();
IntentRuleType type = IntentRuleType.POSITIVE;
if (typeStr == "NEGATIVE")
{
type = IntentRuleType.NEGATIVE;
}
rule.type = type;
List<string> ruleSecs = tmps[2].Trim().Split(';').ToList();
rule.ruleSecs = ruleSecs;
rule.id = rule.intentName + "-" + seqNo.ToString();
seqNo += 1;
list.Add(rule);
}
}*/
return list;
}
public List<EntityData> ParseEntityData()
{
List<EntityData> list = new List<EntityData>();
string[] fileNamess = Directory.GetFiles(rootPath, "entitymap*.json").Select(Path.GetFileName).ToArray();
foreach (string fileName in fileNamess)
{
string content = File.ReadAllText(this.rootPath + fileName);
list.AddRange(JsonConvert.DeserializeObject<List<EntityData>>(content));
}
/*List<string> lines = new List<string>();
foreach (string fileName in fileNamess)
{
string content = File.ReadAllText(rootPath + fileName);
lines.AddRange(content.Split('\n').ToList<string>());
}
int seqNo = 1;
foreach (string line in lines)
{
string theLine = line.Trim();
string[] tmps = theLine.Split('\t');
if (tmps.Count() != 4)
{
throw new Exception("invalid line in entitymap.tsv");
}
else
{
string intentName = tmps[0].Trim();
string similarWord = tmps[1].Trim();
string entityValue = tmps[2].Trim();
string entityType = tmps[3].Trim();
EntityData entity = new EntityData();
entity.id = intentName + "-" + seqNo.ToString();
entity.intentName = intentName;
entity.similarWord = similarWord;
entity.entityValue = entityValue;
entity.entityType = entityType;
list.Add(entity);
seqNo += 1;
}
}
*/
return list;
}
public List<EntityAttributeData> ParseEntityAttributeData()
{
List<EntityAttributeData> list = new List<EntityAttributeData>();
string[] fileNamess = Directory.GetFiles(rootPath, "entityAttributeMap*.json").Select(Path.GetFileName).ToArray();
foreach (string fileName in fileNamess)
{
string content = File.ReadAllText(this.rootPath + fileName);
list.AddRange(JsonConvert.DeserializeObject<List<EntityAttributeData>>(content));
}
/*List<string> lines = new List<string>();
foreach (string fileName in fileNamess)
{
string content = File.ReadAllText(rootPath + fileName);
lines.AddRange(content.Split('\n').ToList<string>());
}
int seqNo = 1;
foreach (string line in lines)
{
string theLine = line.Trim();
if (string.IsNullOrWhiteSpace(theLine))
{
continue;
}
string[] tmps = theLine.Split('\t');
if (tmps.Count() != 5)
{
throw new Exception("invalid line in entityAttributeMap.tsv");
}
else
{
string intentName = tmps[0];
string entityValue = tmps[1];
string entityType = tmps[2];
string attributeName = tmps[3];
string attributeValue = tmps[4];
EntityAttributeData ea = new EntityAttributeData();
ea.id = intentName + "-" + entityValue + "-" + seqNo.ToString();
ea.intentName = intentName;
ea.entityValue = entityValue;
ea.entityType = entityType;
ea.attributeName = attributeName;
ea.attributeValue = attributeValue;
list.Add(ea);
seqNo += 1;
}
}
*/
return list;
}
}
}

View File

@ -0,0 +1,45 @@
using Newtonsoft.Json;
using Serilog;
using SmartKG.Common.Data.Visulization;
using SmartKG.Common.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace SmartKG.Common.Importer
{
public class VisuliaztionImporter
{
private string rootPath;
private List<VisulizationConfig> vConfig;
private ILogger log;
public VisuliaztionImporter(string rootPath)
{
log = Log.Logger.ForContext<VisuliaztionImporter>();
if (string.IsNullOrWhiteSpace(rootPath))
{
throw new Exception("Rootpath of VisulizationConfig files are invalid.");
}
this.rootPath = PathUtility.CompletePath(rootPath);
string[] fileNamess = Directory.GetFiles(this.rootPath, "VisulizationConfig*.json").Select(Path.GetFileName).ToArray();
this.vConfig = new List<VisulizationConfig>();
foreach (string fileName in fileNamess)
{
string content = File.ReadAllText(this.rootPath + fileName);
this.vConfig.AddRange(JsonConvert.DeserializeObject<List<VisulizationConfig>>(content));
}
}
public List<VisulizationConfig> GetVisuliaztionConfigs()
{
return this.vConfig;
}
}
}

View File

@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
namespace SmartKG.Common.Logger
{
public interface KGBotLogHandler
{
void LogInformation(Serilog.ILogger log, string title, string content);
void LogError(Serilog.ILogger log, Exception e);
}
}

View File

@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.Runtime.CompilerServices;
using Serilog;
namespace SmartKG.Common.Logger
{
public static class LoggerExtensions
{
public static ILogger Here(this ILogger logger,
[ContextStatic] string sourceContext = "",
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
return logger.ForContext("MemberName", memberName)
.ForContext("FilePath", sourceFilePath)
.ForContext("LineNumber", sourceLineNumber);
}
}
}

View File

@ -0,0 +1,239 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using Serilog;
using SmartKG.Common.Data.KG;
using SmartKG.Common.Data.Visulization;
using SmartKG.Common.DataStoreMgmt;
namespace SmartKG.Common.Parser.DataPersistance
{
public class DataPersistanceKGParser
{
public static string defaultRelationType = "contains";
private ILogger log;
public DataPersistanceKGParser()
{
log = Log.Logger.ForContext<DataPersistanceKGParser>();
}
private (Dictionary<string, HashSet<string>>, Dictionary<string, Dictionary<RelationLink, List<string>>>, Dictionary<string, Dictionary<RelationLink, List<string>>>, Dictionary<string, List<Edge>>) GenerateRelationship(List<Vertex> vertexes, List<Edge> edges)
{
Dictionary<string, string> vertexIdNameMap = new Dictionary<string, string>();
Dictionary<string, HashSet<string>> vertexNameIdsMap = new Dictionary<string, HashSet<string>>();
foreach (Vertex vertex in vertexes)
{
vertexIdNameMap.Add(vertex.id, vertex.name);
if (vertexNameIdsMap.ContainsKey(vertex.name))
{
vertexNameIdsMap[vertex.name].Add(vertex.id);
}
else
{
HashSet<string> idSet = new HashSet<string>();
idSet.Add(vertex.id);
vertexNameIdsMap.Add(vertex.name, idSet);
}
}
Dictionary<string, Dictionary<RelationLink, List<string>>> outRelationMap = new Dictionary<string, Dictionary<RelationLink, List<string>>>();
Dictionary<string, Dictionary<RelationLink, List<string>>> inRelationMap = new Dictionary<string, Dictionary<RelationLink, List<string>>>();
Dictionary<string, List<Edge>> scenarioEdgesMap = new Dictionary<string, List<Edge>>();
foreach (Edge edge in edges)
{
if (edge.scenarios != null && edge.scenarios.Count > 0)
{
foreach(string scenario in edge.scenarios)
{
if (!scenarioEdgesMap.ContainsKey(scenario))
{
List<Edge> edgesForScenario = new List<Edge>();
scenarioEdgesMap.Add(scenario, edgesForScenario);
}
scenarioEdgesMap[scenario].Add(edge);
}
}
string headVertexId = edge.headVertexId;
string tailVertexId = edge.tailVertexId;
string relationType = edge.relationType;
if (!vertexIdNameMap.ContainsKey(headVertexId) || !vertexIdNameMap.ContainsKey(tailVertexId))
{
log.Warning("VertexId is invalid: " + headVertexId + "; " + tailVertexId);
continue;
}
if (relationType == null)
{
log.Warning("relationType is empty in Edge from " + headVertexId + " to " + tailVertexId + ".\nIf you have no dedicated scenarios, please set the default value of relationType as \"contains\"");
continue;
}
if (edge.scenarios == null || edge.scenarios.Count == 0)
{
log.Warning("scenarios is empty in Edge from " + headVertexId + " to " + tailVertexId + ".\nIf you have no dedicated scenarios, please set the default value of secanrios as [\"Default\"]");
continue;
}
List<RelationLink> links = new List<RelationLink>();
foreach (string scenarioName in edge.scenarios)
{
links.Add(new RelationLink(relationType, scenarioName));
}
foreach (RelationLink link in links)
{
// --- Create outRelationDict
string vertexId = headVertexId;
string childrenId = tailVertexId;
Dictionary<RelationLink, List<string>> outLinkDict;
if (!outRelationMap.ContainsKey(vertexId))
{
outLinkDict = new Dictionary<RelationLink, List<string>>();
outLinkDict.Add(link, new List<string> { childrenId });
outRelationMap.Add(vertexId, outLinkDict);
}
else
{
outLinkDict = outRelationMap[vertexId];
bool inserted = false;
foreach(RelationLink savedLink in outLinkDict.Keys)
{
if (savedLink.Equals(link))
{
outLinkDict[savedLink].Add(childrenId);
inserted = true;
break;
}
}
if (!inserted)
{
outLinkDict.Add(link, new List<string> { childrenId });
}
}
// --- Create inRelationDict
vertexId = tailVertexId;
string parentId = headVertexId;
Dictionary<RelationLink, List<string>> inLinkDict;
if (!inRelationMap.ContainsKey(vertexId))
{
inLinkDict = new Dictionary<RelationLink, List<string>>();
inLinkDict.Add(link, new List<string> { parentId });
inRelationMap.Add(vertexId, inLinkDict);
}
else
{
inLinkDict = inRelationMap[vertexId];
bool inserted = false;
foreach (RelationLink savedLink in inLinkDict.Keys)
{
if (savedLink.Equals(link))
{
inLinkDict[savedLink].Add(parentId);
inserted = true;
break;
}
}
if (!inserted)
{
inLinkDict.Add(link, new List<string> { parentId });
}
}
}
}
return (vertexNameIdsMap, outRelationMap, inRelationMap, scenarioEdgesMap);
}
public KGConfigFrame ParseKGConfig(List<VisulizationConfig> vcList)
{
KGConfigFrame kgConfigFrame = new KGConfigFrame();
Dictionary<string, List<ColorConfig>> vertexLabelsMap = new Dictionary<string, List<ColorConfig>>();
foreach (VisulizationConfig vc in vcList)
{
string scenarioName = vc.scenario;
List<ColorConfig> cc = vc.labelsOfVertexes;
vertexLabelsMap.Add(scenarioName, cc);
}
kgConfigFrame.SetVertexLabelColorMap(vertexLabelsMap);
return kgConfigFrame;
}
public KnowledgeGraphDataFrame ParseKG(List<Vertex> vertexes, List<Edge> edges)
{
(Dictionary<string, HashSet<string>> nameIdMap, Dictionary<string, Dictionary<RelationLink, List<string>>> outRelationDict, Dictionary<string, Dictionary<RelationLink, List<string>>> inRelationDict, Dictionary<string, List<Edge>> scenarioEdgesMap) = this.GenerateRelationship(vertexes, edges);
Dictionary<string, List<Vertex>> vNameCache = new Dictionary<string, List<Vertex>>();
Dictionary<string, Vertex> vIdCache = new Dictionary<string, Vertex>();
List<Vertex> roots = new List<Vertex>();
HashSet<string> scenarioNames = new HashSet<string>();
foreach (Vertex vertex in vertexes)
{
scenarioNames.UnionWith(vertex.scenarios);
if (vertex.nodeType == "ROOT")
{
roots.Add(vertex);
}
if (vNameCache.ContainsKey(vertex.name))
{
vNameCache[vertex.name].Add(vertex);
}
else
{
List<Vertex> vertexesGroupedByName = new List<Vertex>();
vertexesGroupedByName.Add(vertex);
vNameCache.Add(vertex.name, vertexesGroupedByName);
}
vIdCache.Add(vertex.id, vertex);
}
KnowledgeGraphDataFrame kgDF = new KnowledgeGraphDataFrame();
kgDF.SetRootVertexes(roots);
kgDF.SetVertexIdCache(vIdCache);
kgDF.SetVertexNameCache(vNameCache);
kgDF.SetOutRelationDict(outRelationDict);
kgDF.SetInRelationDict(inRelationDict);
kgDF.SetScenarioEdgesDict(scenarioEdgesMap);
kgDF.SetScenarioNames(scenarioNames);
return kgDF;
}
}
}

View File

@ -0,0 +1,105 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System.Collections.Generic;
using SmartKG.Common.Data;
using System;
using Serilog;
using SmartKG.Common.Data.LU;
using SmartKG.Common.Data.KG;
using SmartKG.Common.DataStoreMgmt;
namespace SmartKG.Common.DataPersistance
{
public class DataPersistanceNLUParser
{
private ILogger log;
public DataPersistanceNLUParser()
{
log = Log.Logger.ForContext<DataPersistanceNLUParser>();
}
public NLUDataFrame Parse(List<NLUIntentRule> iList, List<EntityData> eList, List<EntityAttributeData> eaList)
{
NLUDataFrame nluDF = new NLUDataFrame();
if (iList == null || iList.Count == 0)
{
//throw new Exception("No Intent is defined.");
log.Warning("No Intent is defined.");
}
else
{
foreach (NLUIntentRule intentRule in iList)
{
nluDF.AddIntentRule(intentRule);
}
}
if (eList == null || eList.Count == 0)
{
//throw new Exception("No Entity is defined.");
log.Warning("No Entity is defined.");
}
else
{
foreach (EntityData entity in eList)
{
NLUEntity nluEntity = nluDF.AddEntity(entity.intentName, entity.entityValue, entity.entityType);
nluDF.AddSimilarWord(entity.intentName, entity.similarWord, nluEntity);
}
}
if (eaList == null || eaList.Count == 0)
{
Log.Information("There is not any entity attribute defined.");
}
else
{
foreach (EntityAttributeData ea in eaList)
{
nluDF.AddAttribute(ea.intentName, new NLUEntity(ea.entityValue, ea.entityType), new AttributePair(ea.attributeName, ea.attributeValue));
}
}
return nluDF;
}
public void ParseScenarioSettings(NLUDataFrame nluDF, List<ScenarioSetting> kgSettings, List<Vertex> rootVertexes)
{
Dictionary<string, ScenarioSetting> scenarioCache = new Dictionary<string, ScenarioSetting>();
if (kgSettings != null && kgSettings.Count > 0)
{
foreach (ScenarioSetting setting in kgSettings)
{
scenarioCache.Add(setting.scenarioName, setting);
}
}
foreach (Vertex vertex in rootVertexes)
{
if (vertex.nodeType == "ROOT" && vertex.scenarios != null)
{
foreach(string scenarioName in vertex.scenarios)
{
if (scenarioCache.ContainsKey(scenarioName))
{
scenarioCache[scenarioName].root = vertex;
}
else
{
ScenarioSetting defaultSetting = new ScenarioSetting(scenarioName, vertex);
scenarioCache.Add(scenarioName, defaultSetting);
}
}
}
}
nluDF.SetSceanrioCache(scenarioCache);
}
}
}

View File

@ -0,0 +1,143 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using OfficeOpenXml;
using SmartKG.Common.Data.KG;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace SmartKG.Common.Parser
{
public class ExcelParser
{
public (List<Vertex>, List<Edge>) ParserExcel(string path, string scenario)
{
var fi = new FileInfo(path);
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
Dictionary<string, Vertex> vRows = new Dictionary<string, Vertex>();
Dictionary<string, Edge> eRows = new Dictionary<string, Edge>();
using (ExcelPackage package = new ExcelPackage(fi))
{
//get the first worksheet in the workbook
ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
int colCount = worksheet.Dimension.End.Column; //get Column Count
int rowCount = worksheet.Dimension.End.Row; //get row count
for (int row = 2; row <= rowCount; row++)
{
Vertex aVertex = new Vertex();
aVertex.properties = new List<VertexProperty>();
aVertex.scenarios = new List<string>() { scenario};
VertexProperty p = null;
for (int col = 1; col <= colCount; col++)
{
string cellStr = worksheet.Cells[row, col].Value?.ToString().Trim();
if (!string.IsNullOrWhiteSpace(cellStr))
{
switch (col)
{
case 1:
aVertex.id = cellStr + "_" + scenario;
break;
case 2:
aVertex.name = cellStr;
break;
case 3:
aVertex.label = cellStr;
break;
case 4:
aVertex.leadSentence = cellStr;
break;
default:
if (col % 2 == 1)
{
p = new VertexProperty();
p.name = cellStr;
col += 1;
cellStr = worksheet.Cells[row, col].Value?.ToString().Trim();
if (!string.IsNullOrWhiteSpace(cellStr))
{
p.value = cellStr;
aVertex.properties.Add(p);
}
}
break;
}
}
}
if (!string.IsNullOrWhiteSpace(aVertex.id) && !string.IsNullOrWhiteSpace(aVertex.name) && !string.IsNullOrWhiteSpace(aVertex.label))
{
if (!vRows.ContainsKey(aVertex.id))
{
vRows.Add(aVertex.id, aVertex);
}
}
}
worksheet = package.Workbook.Worksheets[1];
colCount = worksheet.Dimension.End.Column; //get Column Count
rowCount = worksheet.Dimension.End.Row; //get row count
for (int row = 2; row <= rowCount; row++)
{
Edge aEdge = new Edge();
aEdge.scenarios = new List<string>() { scenario };
for (int col = 1; col <= colCount; col++)
{
string cellStr = worksheet.Cells[row, col].Value?.ToString().Trim();
if (!string.IsNullOrWhiteSpace(cellStr))
{
switch (col)
{
case 1:
aEdge.relationType = cellStr;
break;
case 2:
aEdge.headVertexId = cellStr + "_" + scenario;
break;
case 3:
aEdge.tailVertexId = cellStr + "_" + scenario;
break;
}
}
}
if (!string.IsNullOrWhiteSpace(aEdge.relationType) && !string.IsNullOrWhiteSpace(aEdge.headVertexId) && !string.IsNullOrWhiteSpace(aEdge.tailVertexId))
{
if (vRows.ContainsKey(aEdge.headVertexId) && vRows.ContainsKey(aEdge.tailVertexId))
{
string key = aEdge.relationType + aEdge.headVertexId + aEdge.tailVertexId;
if (!eRows.ContainsKey(key))
{
eRows.Add(key, aEdge);
}
}
}
}
}
return (vRows.Values.ToList<Vertex>(), eRows.Values.ToList<Edge>());
}
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1.16</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="EPPlus" Version="5.5.3" />
<PackageReference Include="MongoDB.Driver" Version="2.9.2" />
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using SmartKG.Common.Data.Visulization;
namespace SmartKG.Common.Utils
{
public class KGUtility
{
private static string GenerateIdForProperty(string name, string value)
{
string propertyId = name + ":" + value;
return propertyId;
}
public static VisulizedVertex GeneratePropertyVVertex(string vertexLabel, string pName, string pValue)
{
if (string.IsNullOrWhiteSpace(vertexLabel))
vertexLabel = "";
else
vertexLabel = "_" + vertexLabel;
VisulizedVertex propertyVV = new VisulizedVertex();
propertyVV.name = pValue;
propertyVV.displayName = pName;
propertyVV.label = vertexLabel + "属性";
propertyVV.id = GenerateIdForProperty(pName, pValue);
return propertyVV;
}
}
}

Some files were not shown because too many files have changed in this diff Show More