背景
在生产环境中,对于各个设备的属性往特别多,填写繁琐。但是各个设备往往有具有一定的规律。如果找到这种规律,在用户填写部分字段时,自动将其他字段填写完整,用户只需要核查未填写的字段,或者修改少量字段。这样将会很大的提高数据录入的效率。基于此我们需要对数据库中的字段进行分析。并形成可以实际运用的模型数据。
Neo4j
图数据库就很好的反应出这种属性与属性之间的关系。
环境搭建
- 采用的是
Spring Boot 2.0.0.RELEASE
。1.5.9.RELEASE
会有部分问题,最好采用2.0.0.RELEASE
。
- pom.xml, 只摘录了重点部分。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version> 2.0.0.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<!-- http驱动 -->
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-http-driver</artifactId>
</dependency>
2.编写configure
@Configuration
@EnableNeo4jRepositories(basePackages = "com.yinc.gis.neo4j.respository")
@EnableTransactionManagement
public class Neo4jConfiguration{
@Bean
public SessionFactory sessionFactory() {
// with domain entity base package(s)
return new SessionFactory(configuration(), "com.yinc.gis.neo4j.domain");
}
@Bean
public org.neo4j.ogm.config.Configuration configuration() {
ConfigurationSource properties = new ClasspathConfigurationSource("ogm.properties");
org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration.Builder(properties).build();
return configuration;
}
@Bean
public Neo4jTransactionManager transactionManager() {
return new Neo4jTransactionManager(sessionFactory());
}
}
ogm.properties
URI=http://neo4j:yinc@127.0.0.1:7474
driver=org.neo4j.ogm.drivers.http.driver.HttpDriver
username=neo4j
password=yinc
3.编写Repository、NodeEntity
@NodeEntity(label = "Field")
public class Field {
public @Id @GeneratedValue Long id;
public @Property String name; //字段名
public @Property String table; //所属表
public @Property String value; //值
public @Property String caption; //显示用
private @Relationship(type = "LINK", direction=Relationship.UNDIRECTED) Set<Link> link = new HashSet<>();
...省略set get
}
@RelationshipEntity(type = "LINK")
public class Link {
private @Id @GeneratedValue Long id;
private @StartNode Field start; //开始节点
private int weight; //权重
private @EndNode Field end; //结束节点
...省略set get
@Repository
public interface FieldRepository extends Neo4jRepository<Field, Long> {
@Query("UNWIND {field} as map MATCH (n: Field) WHERE n.name=map.name AND n.value=map.value AND n.table=map.table RETURN n")
Optional<Field> getField(@Param("field") Field field);
}
@Repository
public interface LinkRepository extends Neo4jRepository<Link, Long> {
}
4.编写逻辑类
@Service
public class Neo4jBizc {
@Autowired FieldRepository fieldRepo;
@Autowired LinkRepository linkRepo;
//此为查询生成数据库使用mybaits 此文章没有贴出这部分代码
@Autowired TsbznyczbyqMapper mapper;
public void test(){
Map<String,String> sqlMap = new HashMap();
String sql = "select * from T_SB_XXX";
sqlMap.put("querySql", sql);
String[] cols = new String[]{"ZCXZ", "EDDY", "DYB", "KZDL", "YH", "DYDJ", "SCCJ", "SYHJ", "JYNRDJ", "YT", "JYJZ", "RZXS", "JGXS", "LQFS", "DYFS"};
String[] captions = new String[]{"资产性质", "额定电压", "电压比", "空载电流", "油号", "电压等级", "生产厂家",
"使用环境", "绝缘耐热等级", "用途", "绝缘介质", "绕组型式", "结构型式", "冷却方式", "调压方式"};
String table = "T_SB_ZNYC_ZBYQ";
List<Map<String, Object>> rows = mapper.querySbs(sqlMap);
for(Map<String, Object> row: rows){
Field[] fields = new Field[cols.length];
int i = 0;
//查找、保存
for(String col: cols){
String name = col;
String value = "";
if(null != row.get(col)){
value = String.valueOf(row.get(col));
}
Field field = new Field(name, value, table);
Optional<Field> node = fieldRepo.getField(field);
if(node.isPresent()){
//存在
field = node.get();
fields[i] = fieldRepo.findById(field.getId()).get();
} else {
//不存在
String caption = captions[i] + "("+value+")";
field.setCaption(caption);
fields[i] = fieldRepo.save(field);
}
i++;
}
//生成关联关系
for(int k = 0, lenk = fields.length; k < lenk; k++){
Field fieldPoint = fields[k];
for(int j = k+1, len = fields.length; j < len; j++){
Field _field = fields[j];
boolean isExist = false;
Set<Link> links = fieldPoint.getLink();
Iterator<Link> it = links.iterator();
while(it.hasNext()){
Link link = it.next();
Field endField = link.getEnd();
if(/*_field.getId() == endField.getId() ||*/ _field.getId().equals(endField.getId())){
isExist = true;
int weight = link.getWeight();
link.setWeight(weight + 1);
break;
}
}
if(!isExist) {
Link newLink = new Link();
newLink.setWeight(1);
newLink.setStart(fieldPoint);
newLink.setEnd(_field);
links.add(newLink);
}
}
fieldRepo.save(fieldPoint);
}
}
}
}
5.执行后。
match(n:Field)-[r:LINK]-(m:Field) where r.weight > 1 return n,r,m

图中只部分显示了
weight
大于1的节点。
当我们知道某一个属性时,通过插叙找出关联字段,根据weight
来过滤,找出合适的值。
目前这个还一个思路,待具体实现。
网友评论