feat(reasoner): init openspg catalog (#34)

This commit is contained in:
臻至 2023-12-13 15:28:01 +08:00 committed by GitHub
parent 4f44be6313
commit 1b6d45d8a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1168 additions and 1 deletions

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2023 Ant Group CO., Ltd.
~
~ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software distributed under the License
~ is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
~ or implied.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.antgroup.openspg.reasoner</groupId>
<artifactId>reasoner-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>reasoner-openspg-catalog</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.antgroup.openspg.reasoner</groupId>
<artifactId>reasoner-common</artifactId>
</dependency>
<dependency>
<groupId>com.antgroup.openspg.reasoner</groupId>
<artifactId>reasoner-lube-api</artifactId>
</dependency>
<dependency>
<groupId>com.antgroup.openspg.reasoner</groupId>
<artifactId>reasoner-kgdsl-parser</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
</dependency>
<dependency>
<groupId>com.antgroup.openspg.server</groupId>
<artifactId>api-http-client</artifactId>
</dependency>
<dependency>
<groupId>com.antgroup.openspg.server</groupId>
<artifactId>core-schema-model</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,104 @@
/*
* Copyright 2023 Ant Group CO., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
*/
package com.antgroup.openspg.reasoner.catalog.impl.struct;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@Data
public class ConceptRule {
@JSONField(name = "relation")
private String relation;
@JSONField(name = "objectMetaType")
private String objectMetaType;
@JSONField(name = "objectConcept")
private String objectConcept;
@JSONField(name = "dsl")
private String dsl;
/**
* Getter method for property relation.
*
* @return property value of relation
*/
public String getRelation() {
return relation;
}
/**
* Setter method for property relation.
*
* @param relation value to be assigned to property relation
*/
public void setRelation(String relation) {
this.relation = relation;
}
/**
* Getter method for property objectMetaType.
*
* @return property value of objectMetaType
*/
public String getObjectMetaType() {
return objectMetaType;
}
/**
* Setter method for property objectMetaType.
*
* @param objectMetaType value to be assigned to property objectMetaType
*/
public void setObjectMetaType(String objectMetaType) {
this.objectMetaType = objectMetaType;
}
/**
* Getter method for property objectConcept.
*
* @return property value of objectConcept
*/
public String getObjectConcept() {
return objectConcept;
}
/**
* Setter method for property objectConcept.
*
* @param objectConcept value to be assigned to property objectConcept
*/
public void setObjectConcept(String objectConcept) {
this.objectConcept = objectConcept;
}
/**
* Getter method for property dsl.
*
* @return property value of dsl
*/
public String getDsl() {
return dsl;
}
/**
* Setter method for property dsl.
*
* @param dsl value to be assigned to property dsl
*/
public void setDsl(String dsl) {
this.dsl = dsl;
}
}

View File

@ -0,0 +1,144 @@
/*
* Copyright 2023 Ant Group CO., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
*/
package com.antgroup.openspg.reasoner.catalog.impl.struct;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@Data
public class PropertyMeta {
@JSONField(name = "id")
private Long id;
@JSONField(name = "name")
private String name;
@JSONField(name = "attrRangeDetail")
private PropertyRangeDetail propRange;
@JSONField(name = "propertyCategoryEnum")
private String category;
@JSONField(name = "spreadable")
private boolean spreadable;
@JSONField(name = "transformerDetail")
private TransformerDetail transformerDetail;
@JSONField(name = "logicRule")
private Rule logicRule;
/**
* Getter method for property logicalRule.
*
* @return property value of logicalRule
*/
public Rule getLogicRule() {
return logicRule;
}
/**
* Setter method for property logicalRule.
*
* @param logicRule value to be assigned to property logicalRule
*/
public void setLogicRule(Rule logicRule) {
this.logicRule = logicRule;
}
/**
* Getter method for property name.
*
* @return property value of name
*/
public String getName() {
return name;
}
/**
* Setter method for property name.
*
* @param name value to be assigned to property name
*/
public void setName(String name) {
this.name = name;
}
/**
* Getter method for property propRange.
*
* @return property value of propRange
*/
public PropertyRangeDetail getPropRange() {
return propRange;
}
/**
* Setter method for property propRange.
*
* @param propRange value to be assigned to property propRange
*/
public void setPropRange(PropertyRangeDetail propRange) {
this.propRange = propRange;
}
/**
* Getter method for property category.
*
* @return property value of category
*/
public String getCategory() {
return category;
}
/**
* Setter method for property category.
*
* @param category value to be assigned to property category
*/
public void setCategory(String category) {
this.category = category;
}
public boolean isSpreadable() {
return spreadable;
}
/**
* Setter method for property spreadable.
*
* @param spreadable value to be assigned to property spreadable
*/
public void setSpreadable(boolean spreadable) {
this.spreadable = spreadable;
}
/**
* Getter method for property transformerDetail.
*
* @return property value of transformerDetail
*/
public TransformerDetail getTransformerDetail() {
return transformerDetail;
}
/**
* Setter method for property transformerDetail.
*
* @param transformerDetail value to be assigned to property transformerDetail
*/
public void setTransformerDetail(TransformerDetail transformerDetail) {
this.transformerDetail = transformerDetail;
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright 2023 Ant Group CO., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
*/
package com.antgroup.openspg.reasoner.catalog.impl.struct;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@Data
public class PropertyRangeDetail {
@JSONField(name = "id")
private long id;
@JSONField(name = "rangeEntityName")
private String rangeEntityName;
@JSONField(name = "attrRangeTypeEnumCode")
private String attrRangeTypeEnum;
/**
* Getter method for property rangeEntityName.
*
* @return property value of rangeEntityName
*/
public String getRangeEntityName() {
return rangeEntityName;
}
/**
* Getter method for property attrRangeTypeEnum.
*
* @return property value of attrRangeTypeEnum
*/
public String getAttrRangeTypeEnum() {
return attrRangeTypeEnum;
}
/**
* Setter method for property attrRangeTypeEnum.
*
* @param attrRangeTypeEnum value to be assigned to property attrRangeTypeEnum
*/
public void setAttrRangeTypeEnum(String attrRangeTypeEnum) {
this.attrRangeTypeEnum = attrRangeTypeEnum;
}
}

View File

@ -0,0 +1,159 @@
/*
* Copyright 2023 Ant Group CO., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
*/
package com.antgroup.openspg.reasoner.catalog.impl.struct;
import com.alibaba.fastjson.annotation.JSONField;
import java.util.List;
import lombok.Data;
@Data
public class RelationTypeDetail {
@JSONField(name = "id")
private Long id;
@JSONField(name = "name")
private String name;
@JSONField(name = "startEntityTypeDetail")
private VertexMeta startEntityType;
@JSONField(name = "endEntityTypeDetail")
private VertexMeta endEntityType;
@JSONField(name = "attributeTypeDetailList")
private List<PropertyMeta> attributeTypeDetailList;
@JSONField(name = "relationDirectionEnumCode")
private String relationDirectionEnum;
@JSONField(name = "logicRule")
private Rule logicRule;
/**
* Getter method for property logicalRule.
*
* @return property value of logicalRule
*/
public Rule getLogicRule() {
return logicRule;
}
/**
* Setter method for property logicalRule.
*
* @param logicRule value to be assigned to property logicalRule
*/
public void setLogicRule(Rule logicRule) {
this.logicRule = logicRule;
}
/**
* Getter method for property name.
*
* @return property value of name
*/
public Long getId() {
return id;
}
/**
* Getter method for property name.
*
* @return property value of name
*/
public String getName() {
return name;
}
/**
* Setter method for property name.
*
* @param name value to be assigned to property name
*/
public void setName(String name) {
this.name = name;
}
/**
* Getter method for property startEntityType.
*
* @return property value of startEntityType
*/
public VertexMeta getStartEntityType() {
return startEntityType;
}
/**
* Setter method for property startEntityType.
*
* @param startEntityType value to be assigned to property startEntityType
*/
public void setStartEntityType(VertexMeta startEntityType) {
this.startEntityType = startEntityType;
}
/**
* Getter method for property endEntityType.
*
* @return property value of endEntityType
*/
public VertexMeta getEndEntityType() {
return endEntityType;
}
/**
* Setter method for property endEntityType.
*
* @param endEntityType value to be assigned to property endEntityType
*/
public void setEndEntityType(VertexMeta endEntityType) {
this.endEntityType = endEntityType;
}
/**
* Getter method for property attributeTypeDetailList.
*
* @return property value of attributeTypeDetailList
*/
public List<PropertyMeta> getAttributeTypeDetailList() {
return attributeTypeDetailList;
}
/**
* Setter method for property attributeTypeDetailList.
*
* @param attributeTypeDetailList value to be assigned to property attributeTypeDetailList
*/
public void setAttributeTypeDetailList(List<PropertyMeta> attributeTypeDetailList) {
this.attributeTypeDetailList = attributeTypeDetailList;
}
/**
* Getter method for property relationDirectionEnum.
*
* @return property value of relationDirectionEnum
*/
public String getRelationDirectionEnum() {
return relationDirectionEnum;
}
/**
* Setter method for property relationDirectionEnum.
*
* @param relationDirectionEnum value to be assigned to property relationDirectionEnum
*/
public void setRelationDirectionEnum(String relationDirectionEnum) {
this.relationDirectionEnum = relationDirectionEnum;
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 2023 Ant Group CO., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
*/
package com.antgroup.openspg.reasoner.catalog.impl.struct;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@Data
public class Rule {
@JSONField(name = "ruleId")
private String ruleId;
@JSONField(name = "ruleContent")
private String ruleContent;
/**
* Getter method for property ruleId.
*
* @return property value of ruleId
*/
public String getRuleId() {
return ruleId;
}
/**
* Setter method for property ruleId.
*
* @param ruleId value to be assigned to property ruleId
*/
public void setRuleId(String ruleId) {
this.ruleId = ruleId;
}
/**
* Getter method for property ruleContent.
*
* @return property value of ruleContent
*/
public String getRuleContent() {
return ruleContent;
}
/**
* Setter method for property ruleContent.
*
* @param ruleContent value to be assigned to property ruleContent
*/
public void setRuleContent(String ruleContent) {
this.ruleContent = ruleContent;
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright 2023 Ant Group CO., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
*/
package com.antgroup.openspg.reasoner.catalog.impl.struct;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@Data
public class TransformerDetail {
@JSONField(name = "transformerCategoryEnum")
private String transformerCategoryEnum;
/**
* Getter method for property transformerCategoryEnum.
*
* @return property value of transformerCategoryEnum
*/
public String getTransformerCategoryEnum() {
return transformerCategoryEnum;
}
/**
* Setter method for property transformerCategoryEnum.
*
* @param transformerCategoryEnum value to be assigned to property transformerCategoryEnum
*/
public void setTransformerCategoryEnum(String transformerCategoryEnum) {
this.transformerCategoryEnum = transformerCategoryEnum;
}
}

View File

@ -0,0 +1,129 @@
/*
* Copyright 2023 Ant Group CO., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
*/
package com.antgroup.openspg.reasoner.catalog.impl.struct;
import com.alibaba.fastjson.annotation.JSONField;
import java.util.List;
import lombok.Data;
@Data
public class VertexMeta {
@JSONField(name = "id")
private Long id;
@JSONField(name = "name")
private String name;
@JSONField(name = "attributeTypeDetailList")
private List<PropertyMeta> attributeTypeDetailList;
@JSONField(name = "relationTypeDetailList")
private List<RelationTypeDetail> relationTypeDetailList;
@JSONField(name = "inheritAttributeTypeDetailList")
private List<PropertyMeta> inheritAttributeTypeDetailList;
@JSONField(name = "entityCategory")
private String entityCategory;
/**
* Getter method for property entityCategory.
*
* @return property value of entityCategory
*/
public String getEntityCategory() {
return entityCategory;
}
/**
* Setter method for property entityCategory.
*
* @param entityCategory value to be assigned to property entityCategory
*/
public void setEntityCategory(String entityCategory) {
this.entityCategory = entityCategory;
}
/**
* Getter method for property name.
*
* @return property value of name
*/
public Long getId() {
return id;
}
/**
* Getter method for property name.
*
* @return property value of name
*/
public String getName() {
return name;
}
/**
* Setter method for property name.
*
* @param name value to be assigned to property name
*/
public void setName(String name) {
this.name = name;
}
/**
* Getter method for property attributeTypeDetailList.
*
* @return property value of attributeTypeDetailList
*/
public List<PropertyMeta> getAttributeTypeDetailList() {
return attributeTypeDetailList;
}
/**
* Setter method for property attributeTypeDetailList.
*
* @param attributeTypeDetailList value to be assigned to property attributeTypeDetailList
*/
public void setAttributeTypeDetailList(List<PropertyMeta> attributeTypeDetailList) {
this.attributeTypeDetailList = attributeTypeDetailList;
}
/**
* Getter method for property relationTypeDetailList.
*
* @return property value of relationTypeDetailList
*/
public List<RelationTypeDetail> getRelationTypeDetailList() {
return relationTypeDetailList;
}
/**
* Getter method for property relationTypeDetailList.
*
* @return property value of relationTypeDetailList
*/
public List<PropertyMeta> getInheritAttributeTypeDetailList() {
return inheritAttributeTypeDetailList;
}
/**
* Setter method for property relationTypeDetailList.
*
* @param relationTypeDetailList value to be assigned to property relationTypeDetailList
*/
public void setRelationTypeDetailList(List<RelationTypeDetail> relationTypeDetailList) {
this.relationTypeDetailList = relationTypeDetailList;
}
}

View File

@ -0,0 +1,16 @@
/*
* Copyright 2023 Ant Group CO., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
*/
package com.antgroup.openspg.reasoner.catalog.impl
case class KgSchemaConnectionInfo(uri: String, token: String)

View File

@ -0,0 +1,252 @@
/*
* Copyright 2023 Ant Group CO., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
*/
package com.antgroup.openspg.reasoner.catalog.impl
import scala.collection.JavaConverters._
import scala.collection.mutable
import scala.collection.mutable.ListBuffer
import com.antgroup.openspg.core.schema.model.`type`.{BaseAdvancedType, BaseSPGType, BasicType, ProjectSchema}
import com.antgroup.openspg.core.schema.model.predicate.{Property, Relation}
import com.antgroup.openspg.core.schema.model.semantic.DynamicTaxonomySemantic
import com.antgroup.openspg.reasoner.common.constants.Constants
import com.antgroup.openspg.reasoner.common.exception.SchemaException
import com.antgroup.openspg.reasoner.common.graph.edge.SPO
import com.antgroup.openspg.reasoner.common.types.KTString
import com.antgroup.openspg.reasoner.lube.catalog.{AbstractConnection, Catalog, GeneralSemanticRule, PropertyGraphSchema, SemanticPropertyGraph, SemanticRule}
import com.antgroup.openspg.reasoner.lube.catalog.struct.{Edge, Field, Node}
import com.antgroup.openspg.server.api.facade.ApiResponse
import com.antgroup.openspg.server.api.facade.client.{ConceptFacade, SchemaFacade}
import com.antgroup.openspg.server.api.facade.dto.schema.request.{ConceptRequest, ProjectSchemaRequest}
import com.antgroup.openspg.server.api.http.client.{HttpConceptFacade, HttpSchemaFacade}
import com.antgroup.openspg.server.api.http.client.util.{ConnectionInfo, HttpClientBootstrap}
import org.apache.commons.collections4.CollectionUtils
import org.apache.commons.lang3.StringUtils
class OpenSPGCatalog(val projectId: Long,
val connInfo: KgSchemaConnectionInfo,
val projectSchema: ProjectSchema = null) extends Catalog {
if (projectSchema == null) {
HttpClientBootstrap.init(new ConnectionInfo(connInfo.uri))
}
private val spgSchemaFacade: SchemaFacade = new HttpSchemaFacade()
private val spgConceptFacade: ConceptFacade = new HttpConceptFacade()
private val defineRules = new mutable.HashMap[String, SemanticRule]()
/**
* Get schema from knowledge graph
*/
override def getKnowledgeGraph(): SemanticPropertyGraph = {
val realProjectSchema: ProjectSchema =
if (projectSchema == null) {
val request = new ProjectSchemaRequest()
request.setProjectId(projectId)
resultOf(spgSchemaFacade.queryProjectSchema(request))
} else {
projectSchema
}
val nodes: mutable.Map[String, Node] = new mutable.HashMap[String, Node]()
val edges: mutable.Map[SPO, Edge] = new mutable.HashMap[SPO, Edge]
realProjectSchema.getSpgTypes.asScala.foreach(spgType => {
val node = toNode(realProjectSchema, spgType)
if (node != null) {
nodes.put(spgType.getName, node)
val vertexEdges = toEdges(realProjectSchema, spgType)
for (e <- vertexEdges) {
if (edges.contains(e._1)) {
val edgeInfo = edges(e._1)
val mergeSet = edgeInfo.properties ++ e._2.properties
edges += (e._1 -> Edge(
edgeInfo.startNode,
edgeInfo.typeName,
edgeInfo.endNode,
mergeSet,
edgeInfo.resolved))
} else {
edges += e
}
}
}
})
new SemanticPropertyGraph(
Catalog.defaultGraphName,
new PropertyGraphSchema(nodes, edges),
defineRules,
null)
}
private def toNode(projectSchema: ProjectSchema, spgType: BaseSPGType): Node = {
val attrList = new ListBuffer[Field]()
attrList.+=(defaultTypeField)
spgType match {
case _: BasicType =>
null
case advancedType: BaseAdvancedType =>
attrList.++=(advancedType.getProperties.asScala.map(spgProperty => {
toField(projectSchema, spgType, spgProperty)
}))
attrList.++=(getDefaultNodeProperties())
Node(
advancedType.getName,
PropertySchemaOps.toNodeType(spgType.getSpgTypeEnum),
attrList.toSet,
true)
}
}
private def toField(projectSchema: ProjectSchema,
spgType: BaseSPGType,
spgProperty: Property): Field = {
val propertyType = PropertySchemaOps
.stringToKgType2(projectSchema.getByRef(spgProperty.getObjectTypeRef))
val rule = spgProperty.getLogicalRule
val predicateName = spgProperty.getName
if (rule != null && StringUtils.isNotBlank(rule.getContent)) {
defineRules.put(s"${spgType.getName}.${predicateName}", GeneralSemanticRule(rule.getContent))
new Field(predicateName, propertyType, false)
} else {
new Field(predicateName, propertyType, true)
}
}
private def defaultTypeField: Field = {
new Field(Constants.CONTEXT_LABEL, KTString, true)
}
private def toEdges(projectSchema: ProjectSchema, spgType: BaseSPGType): Map[SPO, Edge] = {
if (CollectionUtils.isEmpty(spgType.getRelations)) {
Map.empty
} else {
spgType.getRelations.asScala
.flatMap(relation => toEdge(projectSchema, spgType, relation))
.map(e => (new SPO(e.startNode, e.typeName, e.endNode), e))
.toMap
}
}
private def toEdge(projectSchema: ProjectSchema,
spgType: BaseSPGType,
rel: Relation): List[Edge] = {
val attrList = rel.getSubProperties.asScala.toList
val fields = new ListBuffer[Field]()
val s = spgType.getName
val p = rel.getName
val o = rel.getObjectTypeRef.getName
val spo = new SPO(s, p, o).toString
fields.++=(attrList.map(att => {
val relationType = PropertySchemaOps
.stringToKgType2(projectSchema.getByRef(att.getObjectTypeRef))
new Field(att.getName, relationType, true)
}))
fields.+=(defaultTypeField)
fields.++=(getDefaultEdgeProperties())
val rule = rel.getLogicalRule
if (rule != null && StringUtils.isNotBlank(rule.getContent)) {
defineRules.put(spo, GeneralSemanticRule(rule.getContent))
List.apply(Edge(s, p, o, fields.toSet, false))
} else if (p.equals("belongTo")) {
val request = new ConceptRequest()
request.setConceptTypeName(o)
val concept = resultOf(spgConceptFacade.queryConcept(request))
if (CollectionUtils.isNotEmpty(concept.getConcepts)) {
concept.getConcepts.asScala
.map(r => {
r.getSemantics.asScala.foreach {
case belong: DynamicTaxonomySemantic =>
if (belong.getLogicalRule != null) {
defineRules.put(spo + "/" + r.getName,
GeneralSemanticRule(belong.getLogicalRule.getContent))
}
case _ =>
}
Edge(s, p, o + "/" + r.getName, fields.toSet, false)
})
.toList
} else {
List.apply(Edge(s, p, o, fields.toSet, true))
}
} else {
List.apply(Edge(s, p, o, fields.toSet, true))
}
}
/**
* Get connections of knowledge graph
*
* @return
*/
override def getConnections(): Map[AbstractConnection, Set[String]] = {
val connections = new mutable.HashMap[AbstractConnection, Set[String]]()
graphRepository
.get("KG")
.map(graph => {
val graphSchema = graph.graphSchema
val types = new mutable.HashSet[String]()
types.++=(graphSchema.nodes.keySet)
types.++=(graphSchema.edges.map(x => x._1.toString).toSet)
connections.put(new AbstractConnection {}, types.toSet)
})
connections.toMap
}
private def resultOf[T](apiResponse: ApiResponse[T]): T = {
if (apiResponse.isSuccess) {
apiResponse.getData
} else {
throw SchemaException("Get Schema failed")
}
}
/**
* get default node properties
*
* @return
*/
override def getDefaultNodeProperties()
: Set[Field] = {
Set.apply(
new Field(Constants.NODE_ID_KEY, KTString, true),
new Field(Constants.VERTEX_INTERNAL_ID_KEY, KTString, true),
new Field(Constants.CONTEXT_LABEL, KTString, true))
}
/**
* get default edge properties
*/
override def getDefaultEdgeProperties()
: Set[Field] = {
Set.apply(
new Field(Constants.CONTEXT_LABEL, KTString, true),
new Field(Constants.EDGE_FROM_ID_KEY, KTString, true),
new Field(Constants.EDGE_TO_ID_KEY, KTString, true),
new Field(Constants.EDGE_FROM_INTERNAL_ID_KEY, KTString, true),
new Field(Constants.EDGE_TO_INTERNAL_ID_KEY, KTString, true),
new Field(Constants.EDGE_FROM_ID_TYPE_KEY, KTString, true),
new Field(Constants.EDGE_TO_ID_TYPE_KEY, KTString, true)
)
}
}

View File

@ -0,0 +1,91 @@
/*
* Copyright 2023 Ant Group CO., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
*/
package com.antgroup.openspg.reasoner.catalog.impl
import scala.language.implicitConversions
import com.antgroup.openspg.core.schema.model.`type`.{BaseSPGType, BasicType, ConceptType, EntityType, EventType, SPGTypeEnum, StandardType}
import com.antgroup.openspg.reasoner.catalog.impl.struct.PropertyMeta
import com.antgroup.openspg.reasoner.common.exception.KGValueException
import com.antgroup.openspg.reasoner.common.types._
import com.antgroup.openspg.reasoner.lube.catalog.struct.NodeType
object PropertySchemaOps {
implicit def stringToKgType(propertySchema: PropertyMeta): KgType = {
propertySchema.getCategory match {
case "BASIC" =>
toKgType(propertySchema.getPropRange.getAttrRangeTypeEnum)
case "CONCEPT" =>
KTConcept(propertySchema.getPropRange.getRangeEntityName)
case "STANDARD" =>
KTStd(propertySchema.getPropRange.getRangeEntityName, propertySchema.isSpreadable)
case "PROPERTY" =>
KTStd(propertySchema.getPropRange.getRangeEntityName, propertySchema.isSpreadable)
case "ENTITY" =>
KTAdvanced(propertySchema.getPropRange.getRangeEntityName)
case _ => throw KGValueException(s"unsupported type: ${propertySchema.getCategory}")
}
}
def stringToKgType2(spgType: BaseSPGType): KgType = {
spgType match {
case entityType: EntityType =>
KTAdvanced(entityType.getName)
case conceptType: ConceptType =>
KTConcept(conceptType.getName)
case eventType: EventType =>
// todo
KTAdvanced(eventType.getName)
case standardType: StandardType =>
KTStd(spgType.getName, standardType.getSpreadable)
case basicType: BasicType =>
toKgType(basicType.getBasicType.name())
case _ =>
throw KGValueException(s"unsupported type: ${spgType}")
}
}
private def toKgType(basicType: String): KgType = {
basicType.toUpperCase() match {
case "INTEGER" => KTLong
case "LONG" => KTLong
case "TEXT" => KTString
case "FLOAT" => KTDouble
case "DOUBLE" => KTDouble
case "BOOLEAN" => KTString
case "DATE" => KTString
case "TIME" => KTString
case "URL" => KTString
case "DATETIME" => KTString
case "TIMESTAMP" => KTString
case _ => throw KGValueException(s"unsupported type: $basicType")
}
}
def toNodeType(spgType: SPGTypeEnum): NodeType.Value = {
spgType match {
case SPGTypeEnum.ENTITY_TYPE =>
NodeType.ADVANCED
case SPGTypeEnum.CONCEPT_TYPE =>
NodeType.CONCEPT
case SPGTypeEnum.STANDARD_TYPE =>
NodeType.STANDARD
case SPGTypeEnum.EVENT_TYPE =>
NodeType.EVENT
case _ => throw KGValueException(s"unsupported type: $spgType")
}
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2023 Ant Group CO., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
*/
package com.antgroup.openspg.reasoner.catalog.impl;
import com.antgroup.openspg.reasoner.lube.catalog.SemanticPropertyGraph;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
@Ignore
public class OpenSPGCatalogTest {
public static final KgSchemaConnectionInfo connInfo =
new KgSchemaConnectionInfo("http://127.0.0.1:8887", "a8bB6398B6Da9170");
@Test
public void testGet() {
long projectId = 2L;
OpenSPGCatalog catalog = new OpenSPGCatalog(projectId, connInfo, null);
catalog.init();
SemanticPropertyGraph graph = catalog.getKnowledgeGraph();
Assert.assertNotNull(graph);
}
}

View File

@ -32,7 +32,7 @@ import com.antgroup.openspg.reasoner.lube.common.graph.IRGraph
* and the property graph at runtime
*/
abstract class Catalog() extends Serializable {
private val graphRepository = new mutable.HashMap[String, SemanticPropertyGraph]()
protected val graphRepository = new mutable.HashMap[String, SemanticPropertyGraph]()
private val connections = new mutable.HashMap[String, AbstractConnection]()
/**

View File

@ -29,6 +29,7 @@
<module>udf</module>
<module>lube-api</module>
<module>kgdsl-parser</module>
<module>catalog/openspg-catalog</module>
</modules>
<properties>