Advertisement
bruimafia

Edge Index ElasticSearch

Apr 14th, 2024 (edited)
1,523
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 8.33 KB | None | 0 0
  1. // Класс SchemaLoader
  2. class SchemaLoader(private val project: Project) {
  3.  
  4.     suspend fun loadSchema(
  5.         schema: Schema,
  6.         task: Task? = null
  7.     ) {
  8.         logger.info("Начало загрузки схемы")
  9.  
  10.         task?.let {
  11.             task.switchStage(newStage = TaskStage.UPLOADING_SCHEMA)
  12.             task.changeTotal(newTotal = schema.properties.size)
  13.         }
  14.  
  15.         project.mgmtSuspendTransaction { mgmt ->
  16.  
  17.             val vertexIndex = project.projectKey + "_vertex_index"
  18.             mgmt.buildIndex(vertexIndex, Vertex::class.java).also { builderIndex ->
  19.                 mgmt.createOntologyTags(builderIndex)
  20.  
  21.                 mgmt.createMetaEntity(builderIndex)
  22.  
  23.                 mgmt.createProperties(
  24.                     builderIndex = builderIndex,
  25.                     properties = schema.properties,
  26.                     task = task
  27.                 )
  28.                
  29.                 logger.info("Ожидание создания индекса вершин ${project.projectKey}")
  30.             }.buildMixedIndex("search")
  31.             logger.info("Индекс $vertexIndex для вершин создан")
  32.  
  33.  
  34.             val edgeIndex = project.projectKey + "_edge_index"
  35.             mgmt.buildIndex(edgeIndex, Edge::class.java).also { builderIndex ->
  36.                 mgmt.createEdge(builderIndex)
  37.  
  38.                 logger.info("Ожидание создания индекса ребер ${project.projectKey}")
  39.             }.buildMixedIndex("search")
  40.             logger.info("Индекс $edgeIndex для ребер создан")
  41.         }
  42.  
  43.         project.schema = schema
  44.  
  45.         logger.info("Конец загрузки и индексации схемы")
  46.         task?.let { task.switchStage(newStage = TaskStage.Ready) }
  47.     }
  48.  
  49.     /**
  50.      * Создание свойства для хранения списка онтологических тэгов
  51.      */
  52.     private fun JanusGraphManagement.createOntologyTags(
  53.         builderIndex: JanusGraphManagement.IndexBuilder
  54.     ) {
  55.         //TODO можно создать ONTOLOGICAL_TAGS-single для хранения конечного тэга, кем является сущность.
  56.         // Это может немного оптимизировать конвертацию из Vertex в NodeData
  57.  
  58.         val propertyNameOntologyTags = "${ONTOLOGICAL_TAGS.name}-list"
  59.         val propertyOntologyTags = makePropertyKey(propertyNameOntologyTags)
  60.             .dataType(DataType.STRING.jvmClass)
  61.             .cardinality(Cardinality.LIST).make()
  62.  
  63.         builderIndex.addKey(propertyOntologyTags, Mapping.STRING.asParameter())
  64.     }
  65.  
  66.     /**
  67.      * Создание мета свойств, используемых в истории
  68.      */
  69.     private fun JanusGraphManagement.createMetaEntity(
  70.         builderIndex: JanusGraphManagement.IndexBuilder
  71.     ) {
  72.         //TODO есть возможность индексации Property у VertexProperty,
  73.         // теоретически это может ускорить поиск по временным промежуткам
  74.  
  75.         val metaEntity = listOf(
  76.             MANDATE_LABEL.name to DataType.BYTE,
  77.             NODE_CREATED.name to DataType.LONG,
  78.             LABEL_HISTORY_PROPERTY_LOAD_DATE.name to DataType.LONG,
  79.             LABEL_HISTORY_PROPERTY_COLLECTION_DATE.name to DataType.LONG,
  80.             LABEL_HISTORY_PROPERTY_DATE_OF_DOCUMENT_CREATION.name to DataType.LONG,
  81.             LABEL_USER_CHANGE_PROPERTY_NAME.name to DataType.STRING,
  82.             NON_HIERARCHICAL_PRIVACY_CATEGORIES.name to DataType.BYTE,
  83.             LOADING_ID.name to DataType.STRING,
  84.         )
  85.  
  86.         metaEntity.forEach { (name, type) ->
  87.             val validNameMetaProperty = name.replace("/", "")
  88.  
  89.             val metaPropertyName = "$validNameMetaProperty-single"
  90.  
  91.             val metaProperty = makePropertyKey(metaPropertyName)
  92.                 .dataType(type.jvmClass)
  93.                 .cardinality(Cardinality.SINGLE).make()
  94.  
  95.             builderIndex.addKey(metaProperty)
  96.            
  97.             logger.debug("Добавлено МЕТА-СВОЙСТВО: $validNameMetaProperty")
  98.         }
  99.     }
  100.  
  101.     /**
  102.      * Создание всех свойств в схеме
  103.      */
  104.     private suspend fun JanusGraphManagement.createProperties(
  105.         builderIndex: JanusGraphManagement.IndexBuilder,
  106.         properties: List<PropertySchema>,
  107.         task: Task? = null
  108.     ) {
  109.         properties.forEach { property ->
  110.             val validName = property.key.replace("/", "")
  111.  
  112.             val propertyNameSingle = "$validName-single"
  113.             val propertyNameList = "$validName-list"
  114.  
  115.             val propertySingle = makePropertyKey(propertyNameSingle)
  116.                 .dataTypeConverter(property)
  117.                 .cardinality(Cardinality.SINGLE).make()
  118.  
  119.             val propertyList = makePropertyKey(propertyNameList)
  120.                 .dataTypeConverter(property)
  121.                 .cardinality(Cardinality.LIST).make()
  122.  
  123.             if (property.isIndex) {
  124.  
  125.                 when (property.dataType) {
  126.                     DataType.STRING -> {
  127.                         builderIndex.addKey(propertySingle, Mapping.TEXTSTRING.asParameter())
  128.                         builderIndex.addKey(propertyList, Mapping.TEXTSTRING.asParameter())
  129.                     }
  130.  
  131.                     DataType.GEOSHAPE -> {
  132.                         builderIndex.addKey(propertySingle, Mapping.BKD.asParameter())
  133.                         builderIndex.addKey(propertyList, Mapping.BKD.asParameter())
  134.                     }
  135.  
  136.                     else -> {
  137.                         builderIndex.addKey(propertySingle, Mapping.DEFAULT.asParameter())
  138.                         builderIndex.addKey(propertyList, Mapping.DEFAULT.asParameter())
  139.                     }
  140.                 }
  141.  
  142.             }
  143.  
  144.             task?.let { task.increment() }
  145.  
  146.             logger.debug("Добавлено СВОЙСТВО: $validName")
  147.         }
  148.     }
  149.  
  150.     /**
  151.      * Создание ребра
  152.      */
  153.     private fun JanusGraphManagement.createEdge(
  154.         builderIndex: JanusGraphManagement.IndexBuilder,
  155.     ) {
  156.  
  157.         builderIndex.addKey(edgeNameProperty)
  158.         //builderIndex.addKey(edgeNameProperty, Mapping.TEXTSTRING.asParameter())
  159.        
  160.        
  161.         val metaProperty = makePropertyKey(EDGE_NAME.name)
  162.             .dataType(DataType.STRING.jvmClass)
  163.             .cardinality(Cardinality.SINGLE).make()
  164.  
  165.         val edge = makeEdgeLabel(EDGE.name).multiplicity(Multiplicity.MULTI).make()
  166.         buildEdgeIndex(edge, "edge-index", Direction.BOTH, Order.desc, metaProperty)
  167.  
  168.         val metaEntity = listOf(
  169.             EDGE_NAME.name to DataType.STRING,
  170.         )
  171.  
  172.         metaEntity.forEach { (name, type) ->
  173.             val validNameMetaProperty = name.replace("/", "")
  174.  
  175.             val metaPropertyName = "$validNameMetaProperty-single"
  176.  
  177.             val metaProperty = makePropertyKey(metaPropertyName)
  178.                 .dataType(type.jvmClass)
  179.                 .cardinality(Cardinality.SINGLE).make()
  180.  
  181.             builderIndex.addKey(metaProperty, Mapping.TEXTSTRING.asParameter())
  182.  
  183.             logger.debug("Добавлено РЕБРО: ${validNameMetaProperty}")
  184.         }
  185.        
  186.     }
  187.  
  188.     private fun PropertyKeyMaker.dataTypeConverter(property: PropertySchema): PropertyKeyMaker =
  189.         when (property.dataType) {
  190.             DataType.GEOSHAPE -> dataType(Geoshape::class.java)
  191.             else -> dataType(property.dataType.jvmClass)
  192.         }
  193.        
  194. }
  195.  
  196.  
  197. // Класс EdgeRepository
  198. class EdgeRepository {
  199.     fun createEdge(
  200.         edgeKey: String,
  201.         edgeSourceId: String,
  202.         edgeTargetId: String,
  203.         traversal: GraphTraversalSource,
  204.     ): String =
  205.         traversal
  206.             .addE(EDGE.name)
  207.             .property(EDGE_NAME.single, edgeKey) // добавление мета свойства с именем ребра
  208.             .from(step.V<Edge>(edgeSourceId))
  209.             .to(step.V<Edge>(edgeTargetId))
  210.             .next()
  211.             .id()
  212.             .toString()
  213. }
  214.  
  215.  
  216. // Метод isExistEdge()
  217.  fun isExistEdge() = traversal
  218.             .V().has(LOADING_ID.single, edge.source.id)
  219.             .bothE().has(EDGE_NAME.single, edge.key)
  220.             .otherV().has(LOADING_ID.single, edge.target.id)
  221.             .hasNext()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement