@nshiab/simple-data-analysis-core 2.0.9 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/class/SDAError.d.ts +6 -6
- package/esm/class/SDAError.js +6 -6
- package/esm/class/Simple.d.ts +9 -9
- package/esm/class/Simple.js +9 -9
- package/esm/class/SimpleDB.d.ts +80 -76
- package/esm/class/SimpleDB.d.ts.map +1 -1
- package/esm/class/SimpleDB.js +80 -76
- package/esm/class/SimpleTable.d.ts +2795 -1139
- package/esm/class/SimpleTable.d.ts.map +1 -1
- package/esm/class/SimpleTable.js +2781 -1149
- package/esm/helpers/buildApproximateMutualReachabilityMst.d.ts +45 -0
- package/esm/helpers/buildApproximateMutualReachabilityMst.d.ts.map +1 -0
- package/esm/helpers/buildApproximateMutualReachabilityMst.js +212 -0
- package/esm/helpers/buildChronologicalGraphComponentsSql.d.ts +14 -0
- package/esm/helpers/buildChronologicalGraphComponentsSql.d.ts.map +1 -0
- package/esm/helpers/buildChronologicalGraphComponentsSql.js +167 -0
- package/esm/helpers/buildExactMutualReachabilityMst.d.ts +28 -0
- package/esm/helpers/buildExactMutualReachabilityMst.d.ts.map +1 -0
- package/esm/helpers/buildExactMutualReachabilityMst.js +97 -0
- package/esm/helpers/buildGraphTemporalCostStateSql.d.ts +12 -0
- package/esm/helpers/buildGraphTemporalCostStateSql.d.ts.map +1 -0
- package/esm/helpers/buildGraphTemporalCostStateSql.js +86 -0
- package/esm/helpers/buildGraphTemporalReachabilitySql.d.ts +13 -0
- package/esm/helpers/buildGraphTemporalReachabilitySql.d.ts.map +1 -0
- package/esm/helpers/buildGraphTemporalReachabilitySql.js +70 -0
- package/esm/helpers/buildSparseMutualReachabilityMst.d.ts +10 -0
- package/esm/helpers/buildSparseMutualReachabilityMst.d.ts.map +1 -0
- package/esm/helpers/buildSparseMutualReachabilityMst.js +47 -0
- package/esm/helpers/buildUmapGraph.d.ts +2 -5
- package/esm/helpers/buildUmapGraph.d.ts.map +1 -1
- package/esm/helpers/buildUmapGraph.js +6 -100
- package/esm/helpers/buildVectorNeighbors.d.ts +45 -0
- package/esm/helpers/buildVectorNeighbors.d.ts.map +1 -0
- package/esm/helpers/buildVectorNeighbors.js +170 -0
- package/esm/helpers/buildWeakGraphComponentsSql.d.ts +3 -0
- package/esm/helpers/buildWeakGraphComponentsSql.d.ts.map +1 -0
- package/esm/helpers/buildWeakGraphComponentsSql.js +32 -0
- package/esm/helpers/camelCase.d.ts +7 -5
- package/esm/helpers/camelCase.d.ts.map +1 -1
- package/esm/helpers/camelCase.js +7 -5
- package/esm/helpers/capitalize.d.ts +6 -4
- package/esm/helpers/capitalize.d.ts.map +1 -1
- package/esm/helpers/capitalize.js +6 -4
- package/esm/helpers/clusterHdbscan.d.ts +18 -0
- package/esm/helpers/clusterHdbscan.d.ts.map +1 -0
- package/esm/helpers/clusterHdbscan.js +342 -0
- package/esm/helpers/computeCovariance.d.ts +16 -0
- package/esm/helpers/computeCovariance.d.ts.map +1 -0
- package/esm/helpers/computeCovariance.js +99 -0
- package/esm/helpers/computeMahalanobisDistances.d.ts +14 -0
- package/esm/helpers/computeMahalanobisDistances.d.ts.map +1 -0
- package/esm/helpers/computeMahalanobisDistances.js +87 -0
- package/esm/helpers/createDirectory.d.ts +4 -3
- package/esm/helpers/createDirectory.d.ts.map +1 -1
- package/esm/helpers/createDirectory.js +4 -3
- package/esm/helpers/dataToArrays.d.ts +6 -4
- package/esm/helpers/dataToArrays.d.ts.map +1 -1
- package/esm/helpers/dataToArrays.js +6 -4
- package/esm/helpers/extractTypes.d.ts +1 -1
- package/esm/helpers/extractTypes.js +4 -9
- package/esm/helpers/factorCovariance.d.ts +17 -0
- package/esm/helpers/factorCovariance.d.ts.map +1 -0
- package/esm/helpers/factorCovariance.js +189 -0
- package/esm/helpers/findGeoColumn.d.ts +6 -4
- package/esm/helpers/findGeoColumn.d.ts.map +1 -1
- package/esm/helpers/findGeoColumn.js +6 -4
- package/esm/helpers/findGeoColumnFromSchema.d.ts +8 -5
- package/esm/helpers/findGeoColumnFromSchema.d.ts.map +1 -1
- package/esm/helpers/findGeoColumnFromSchema.js +8 -5
- package/esm/helpers/formatDate.d.ts +12 -6
- package/esm/helpers/formatDate.d.ts.map +1 -1
- package/esm/helpers/formatDate.js +12 -6
- package/esm/helpers/formatMissingTables.d.ts +8 -5
- package/esm/helpers/formatMissingTables.d.ts.map +1 -1
- package/esm/helpers/formatMissingTables.js +8 -5
- package/esm/helpers/formatNumber.d.ts +19 -10
- package/esm/helpers/formatNumber.d.ts.map +1 -1
- package/esm/helpers/formatNumber.js +32 -17
- package/esm/helpers/getGraphEdgeIdColumn.d.ts +9 -0
- package/esm/helpers/getGraphEdgeIdColumn.d.ts.map +1 -0
- package/esm/helpers/getGraphEdgeIdColumn.js +25 -0
- package/esm/helpers/getGraphEndpointColumns.d.ts +11 -0
- package/esm/helpers/getGraphEndpointColumns.d.ts.map +1 -0
- package/esm/helpers/getGraphEndpointColumns.js +160 -0
- package/esm/helpers/getGraphWeightColumn.d.ts +10 -0
- package/esm/helpers/getGraphWeightColumn.d.ts.map +1 -0
- package/esm/helpers/getGraphWeightColumn.js +40 -0
- package/esm/helpers/graphRouteResultSchema.d.ts +4 -0
- package/esm/helpers/graphRouteResultSchema.d.ts.map +1 -0
- package/esm/helpers/graphRouteResultSchema.js +12 -0
- package/esm/helpers/graphRouteResultSelect.d.ts +4 -0
- package/esm/helpers/graphRouteResultSelect.d.ts.map +1 -0
- package/esm/helpers/graphRouteResultSelect.js +22 -0
- package/esm/helpers/hasGeometryColumn.d.ts +4 -3
- package/esm/helpers/hasGeometryColumn.d.ts.map +1 -1
- package/esm/helpers/hasGeometryColumn.js +4 -3
- package/esm/helpers/inspectGraphConnectivity.d.ts +10 -0
- package/esm/helpers/inspectGraphConnectivity.d.ts.map +1 -0
- package/esm/helpers/inspectGraphConnectivity.js +55 -0
- package/esm/helpers/mergeOptions.d.ts +24 -13
- package/esm/helpers/mergeOptions.d.ts.map +1 -1
- package/esm/helpers/mergeOptions.js +24 -13
- package/esm/helpers/parseValue.d.ts +6 -4
- package/esm/helpers/parseValue.d.ts.map +1 -1
- package/esm/helpers/parseValue.js +6 -4
- package/esm/helpers/prepareGraphRouteSql.d.ts +31 -0
- package/esm/helpers/prepareGraphRouteSql.d.ts.map +1 -0
- package/esm/helpers/prepareGraphRouteSql.js +86 -0
- package/esm/helpers/prepareGraphStarts.d.ts +9 -0
- package/esm/helpers/prepareGraphStarts.d.ts.map +1 -0
- package/esm/helpers/prepareGraphStarts.js +68 -0
- package/esm/helpers/prepareGraphTemporalSql.d.ts +28 -0
- package/esm/helpers/prepareGraphTemporalSql.d.ts.map +1 -0
- package/esm/helpers/prepareGraphTemporalSql.js +154 -0
- package/esm/helpers/prepareGraphTraversal.d.ts +19 -0
- package/esm/helpers/prepareGraphTraversal.d.ts.map +1 -0
- package/esm/helpers/prepareGraphTraversal.js +79 -0
- package/esm/helpers/prepareNumericFeatures.d.ts +41 -0
- package/esm/helpers/prepareNumericFeatures.d.ts.map +1 -0
- package/esm/helpers/prepareNumericFeatures.js +210 -0
- package/esm/helpers/prettyDuration.d.ts +14 -8
- package/esm/helpers/prettyDuration.d.ts.map +1 -1
- package/esm/helpers/prettyDuration.js +14 -8
- package/esm/helpers/printTable.d.ts +18 -13
- package/esm/helpers/printTable.d.ts.map +1 -1
- package/esm/helpers/printTable.js +18 -13
- package/esm/helpers/publishPreparedColumns.d.ts +37 -0
- package/esm/helpers/publishPreparedColumns.d.ts.map +1 -0
- package/esm/helpers/publishPreparedColumns.js +113 -0
- package/esm/helpers/queryDB.d.ts +24 -13
- package/esm/helpers/queryDB.d.ts.map +1 -1
- package/esm/helpers/queryDB.js +24 -13
- package/esm/helpers/queueAsyncBarrier.d.ts +12 -7
- package/esm/helpers/queueAsyncBarrier.d.ts.map +1 -1
- package/esm/helpers/queueAsyncBarrier.js +12 -7
- package/esm/helpers/queueGraphResult.d.ts +18 -0
- package/esm/helpers/queueGraphResult.d.ts.map +1 -0
- package/esm/helpers/queueGraphResult.js +39 -0
- package/esm/helpers/quoteIdentifier.d.ts +4 -3
- package/esm/helpers/quoteIdentifier.d.ts.map +1 -1
- package/esm/helpers/quoteIdentifier.js +4 -3
- package/esm/helpers/quoteQualifiedIdentifier.d.ts +6 -4
- package/esm/helpers/quoteQualifiedIdentifier.d.ts.map +1 -1
- package/esm/helpers/quoteQualifiedIdentifier.js +6 -4
- package/esm/helpers/runQuery.d.ts.map +1 -1
- package/esm/helpers/runQuery.js +17 -3
- package/esm/helpers/selectFuzzyReplacements.d.ts +11 -0
- package/esm/helpers/selectFuzzyReplacements.d.ts.map +1 -0
- package/esm/helpers/selectFuzzyReplacements.js +124 -0
- package/esm/helpers/stabilizeCosineVectors.d.ts +14 -0
- package/esm/helpers/stabilizeCosineVectors.d.ts.map +1 -0
- package/esm/helpers/stabilizeCosineVectors.js +34 -0
- package/esm/helpers/stringToArray.d.ts +4 -3
- package/esm/helpers/stringToArray.d.ts.map +1 -1
- package/esm/helpers/stringToArray.js +4 -3
- package/esm/helpers/updateColumnsWithJS.d.ts +12 -6
- package/esm/helpers/updateColumnsWithJS.d.ts.map +1 -1
- package/esm/helpers/updateColumnsWithJS.js +12 -6
- package/esm/helpers/validateGraphRouteResultSchema.d.ts +4 -0
- package/esm/helpers/validateGraphRouteResultSchema.d.ts.map +1 -0
- package/esm/helpers/validateGraphRouteResultSchema.js +13 -0
- package/esm/helpers/validateGraphTemporalEvents.d.ts +7 -0
- package/esm/helpers/validateGraphTemporalEvents.d.ts.map +1 -0
- package/esm/helpers/validateGraphTemporalEvents.js +47 -0
- package/esm/helpers/validateNumericalAnalysis.d.ts +10 -6
- package/esm/helpers/validateNumericalAnalysis.d.ts.map +1 -1
- package/esm/helpers/validateNumericalAnalysis.js +10 -6
- package/esm/helpers/validateVectorRowIds.d.ts +4 -0
- package/esm/helpers/validateVectorRowIds.d.ts.map +1 -0
- package/esm/helpers/validateVectorRowIds.js +16 -0
- package/esm/helpers/vectorDistanceExpression.d.ts +6 -0
- package/esm/helpers/vectorDistanceExpression.d.ts.map +1 -0
- package/esm/helpers/vectorDistanceExpression.js +11 -0
- package/esm/helpers/wrapString.d.ts +10 -7
- package/esm/helpers/wrapString.d.ts.map +1 -1
- package/esm/helpers/wrapString.js +10 -7
- package/esm/methods/addId.d.ts +5 -0
- package/esm/methods/addId.d.ts.map +1 -0
- package/esm/methods/addId.js +38 -0
- package/esm/methods/commonNeighbors.d.ts +10 -0
- package/esm/methods/commonNeighbors.d.ts.map +1 -0
- package/esm/methods/commonNeighbors.js +101 -0
- package/esm/methods/connectedComponents.d.ts +9 -0
- package/esm/methods/connectedComponents.d.ts.map +1 -0
- package/esm/methods/connectedComponents.js +147 -0
- package/esm/methods/degree.d.ts +9 -0
- package/esm/methods/degree.d.ts.map +1 -0
- package/esm/methods/degree.js +135 -0
- package/esm/methods/distances.d.ts +12 -0
- package/esm/methods/distances.d.ts.map +1 -0
- package/esm/methods/distances.js +164 -0
- package/esm/methods/findCycles.d.ts +12 -0
- package/esm/methods/findCycles.d.ts.map +1 -0
- package/esm/methods/findCycles.js +330 -0
- package/esm/methods/fuzzyClean.d.ts.map +1 -1
- package/esm/methods/fuzzyClean.js +17 -136
- package/esm/methods/fuzzyJoin.js +70 -16
- package/esm/methods/getTypes.d.ts +1 -1
- package/esm/methods/hdbscan.d.ts +5 -0
- package/esm/methods/hdbscan.d.ts.map +1 -0
- package/esm/methods/hdbscan.js +208 -0
- package/esm/methods/mahalanobis.d.ts +5 -0
- package/esm/methods/mahalanobis.d.ts.map +1 -0
- package/esm/methods/mahalanobis.js +92 -0
- package/esm/methods/neighbors.d.ts +9 -0
- package/esm/methods/neighbors.d.ts.map +1 -0
- package/esm/methods/neighbors.js +81 -0
- package/esm/methods/normalizeVector.d.ts +5 -0
- package/esm/methods/normalizeVector.d.ts.map +1 -0
- package/esm/methods/normalizeVector.js +132 -0
- package/esm/methods/paths.d.ts +12 -0
- package/esm/methods/paths.d.ts.map +1 -0
- package/esm/methods/paths.js +287 -0
- package/esm/methods/reachable.d.ts +11 -0
- package/esm/methods/reachable.d.ts.map +1 -0
- package/esm/methods/reachable.js +131 -0
- package/esm/methods/rowToVector.d.ts +5 -0
- package/esm/methods/rowToVector.d.ts.map +1 -0
- package/esm/methods/rowToVector.js +77 -0
- package/esm/methods/shortestPath.d.ts +12 -0
- package/esm/methods/shortestPath.d.ts.map +1 -0
- package/esm/methods/shortestPath.js +337 -0
- package/esm/methods/topologicalSort.d.ts +7 -0
- package/esm/methods/topologicalSort.d.ts.map +1 -0
- package/esm/methods/topologicalSort.js +164 -0
- package/llm.md +2106 -143
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/script/class/SDAError.d.ts +6 -6
- package/script/class/SDAError.js +6 -6
- package/script/class/Simple.d.ts +9 -9
- package/script/class/Simple.js +9 -9
- package/script/class/SimpleDB.d.ts +80 -76
- package/script/class/SimpleDB.d.ts.map +1 -1
- package/script/class/SimpleDB.js +80 -76
- package/script/class/SimpleTable.d.ts +2795 -1139
- package/script/class/SimpleTable.d.ts.map +1 -1
- package/script/class/SimpleTable.js +2781 -1149
- package/script/helpers/buildApproximateMutualReachabilityMst.d.ts +45 -0
- package/script/helpers/buildApproximateMutualReachabilityMst.d.ts.map +1 -0
- package/script/helpers/buildApproximateMutualReachabilityMst.js +219 -0
- package/script/helpers/buildChronologicalGraphComponentsSql.d.ts +14 -0
- package/script/helpers/buildChronologicalGraphComponentsSql.d.ts.map +1 -0
- package/script/helpers/buildChronologicalGraphComponentsSql.js +174 -0
- package/script/helpers/buildExactMutualReachabilityMst.d.ts +28 -0
- package/script/helpers/buildExactMutualReachabilityMst.d.ts.map +1 -0
- package/script/helpers/buildExactMutualReachabilityMst.js +103 -0
- package/script/helpers/buildGraphTemporalCostStateSql.d.ts +12 -0
- package/script/helpers/buildGraphTemporalCostStateSql.d.ts.map +1 -0
- package/script/helpers/buildGraphTemporalCostStateSql.js +92 -0
- package/script/helpers/buildGraphTemporalReachabilitySql.d.ts +13 -0
- package/script/helpers/buildGraphTemporalReachabilitySql.d.ts.map +1 -0
- package/script/helpers/buildGraphTemporalReachabilitySql.js +76 -0
- package/script/helpers/buildSparseMutualReachabilityMst.d.ts +10 -0
- package/script/helpers/buildSparseMutualReachabilityMst.d.ts.map +1 -0
- package/script/helpers/buildSparseMutualReachabilityMst.js +50 -0
- package/script/helpers/buildUmapGraph.d.ts +2 -5
- package/script/helpers/buildUmapGraph.d.ts.map +1 -1
- package/script/helpers/buildUmapGraph.js +6 -100
- package/script/helpers/buildVectorNeighbors.d.ts +45 -0
- package/script/helpers/buildVectorNeighbors.d.ts.map +1 -0
- package/script/helpers/buildVectorNeighbors.js +176 -0
- package/script/helpers/buildWeakGraphComponentsSql.d.ts +3 -0
- package/script/helpers/buildWeakGraphComponentsSql.d.ts.map +1 -0
- package/script/helpers/buildWeakGraphComponentsSql.js +38 -0
- package/script/helpers/camelCase.d.ts +7 -5
- package/script/helpers/camelCase.d.ts.map +1 -1
- package/script/helpers/camelCase.js +7 -5
- package/script/helpers/capitalize.d.ts +6 -4
- package/script/helpers/capitalize.d.ts.map +1 -1
- package/script/helpers/capitalize.js +6 -4
- package/script/helpers/clusterHdbscan.d.ts +18 -0
- package/script/helpers/clusterHdbscan.d.ts.map +1 -0
- package/script/helpers/clusterHdbscan.js +346 -0
- package/script/helpers/computeCovariance.d.ts +16 -0
- package/script/helpers/computeCovariance.d.ts.map +1 -0
- package/script/helpers/computeCovariance.js +105 -0
- package/script/helpers/computeMahalanobisDistances.d.ts +14 -0
- package/script/helpers/computeMahalanobisDistances.d.ts.map +1 -0
- package/script/helpers/computeMahalanobisDistances.js +93 -0
- package/script/helpers/createDirectory.d.ts +4 -3
- package/script/helpers/createDirectory.d.ts.map +1 -1
- package/script/helpers/createDirectory.js +4 -3
- package/script/helpers/dataToArrays.d.ts +6 -4
- package/script/helpers/dataToArrays.d.ts.map +1 -1
- package/script/helpers/dataToArrays.js +6 -4
- package/script/helpers/extractTypes.d.ts +1 -1
- package/script/helpers/extractTypes.js +4 -9
- package/script/helpers/factorCovariance.d.ts +17 -0
- package/script/helpers/factorCovariance.d.ts.map +1 -0
- package/script/helpers/factorCovariance.js +194 -0
- package/script/helpers/findGeoColumn.d.ts +6 -4
- package/script/helpers/findGeoColumn.d.ts.map +1 -1
- package/script/helpers/findGeoColumn.js +6 -4
- package/script/helpers/findGeoColumnFromSchema.d.ts +8 -5
- package/script/helpers/findGeoColumnFromSchema.d.ts.map +1 -1
- package/script/helpers/findGeoColumnFromSchema.js +8 -5
- package/script/helpers/formatDate.d.ts +12 -6
- package/script/helpers/formatDate.d.ts.map +1 -1
- package/script/helpers/formatDate.js +12 -6
- package/script/helpers/formatMissingTables.d.ts +8 -5
- package/script/helpers/formatMissingTables.d.ts.map +1 -1
- package/script/helpers/formatMissingTables.js +8 -5
- package/script/helpers/formatNumber.d.ts +19 -10
- package/script/helpers/formatNumber.d.ts.map +1 -1
- package/script/helpers/formatNumber.js +32 -17
- package/script/helpers/getGraphEdgeIdColumn.d.ts +9 -0
- package/script/helpers/getGraphEdgeIdColumn.d.ts.map +1 -0
- package/script/helpers/getGraphEdgeIdColumn.js +31 -0
- package/script/helpers/getGraphEndpointColumns.d.ts +11 -0
- package/script/helpers/getGraphEndpointColumns.d.ts.map +1 -0
- package/script/helpers/getGraphEndpointColumns.js +166 -0
- package/script/helpers/getGraphWeightColumn.d.ts +10 -0
- package/script/helpers/getGraphWeightColumn.d.ts.map +1 -0
- package/script/helpers/getGraphWeightColumn.js +46 -0
- package/script/helpers/graphRouteResultSchema.d.ts +4 -0
- package/script/helpers/graphRouteResultSchema.d.ts.map +1 -0
- package/script/helpers/graphRouteResultSchema.js +18 -0
- package/script/helpers/graphRouteResultSelect.d.ts +4 -0
- package/script/helpers/graphRouteResultSelect.d.ts.map +1 -0
- package/script/helpers/graphRouteResultSelect.js +28 -0
- package/script/helpers/hasGeometryColumn.d.ts +4 -3
- package/script/helpers/hasGeometryColumn.d.ts.map +1 -1
- package/script/helpers/hasGeometryColumn.js +4 -3
- package/script/helpers/inspectGraphConnectivity.d.ts +10 -0
- package/script/helpers/inspectGraphConnectivity.d.ts.map +1 -0
- package/script/helpers/inspectGraphConnectivity.js +58 -0
- package/script/helpers/mergeOptions.d.ts +24 -13
- package/script/helpers/mergeOptions.d.ts.map +1 -1
- package/script/helpers/mergeOptions.js +24 -13
- package/script/helpers/parseValue.d.ts +6 -4
- package/script/helpers/parseValue.d.ts.map +1 -1
- package/script/helpers/parseValue.js +6 -4
- package/script/helpers/prepareGraphRouteSql.d.ts +31 -0
- package/script/helpers/prepareGraphRouteSql.d.ts.map +1 -0
- package/script/helpers/prepareGraphRouteSql.js +127 -0
- package/script/helpers/prepareGraphStarts.d.ts +9 -0
- package/script/helpers/prepareGraphStarts.d.ts.map +1 -0
- package/script/helpers/prepareGraphStarts.js +71 -0
- package/script/helpers/prepareGraphTemporalSql.d.ts +28 -0
- package/script/helpers/prepareGraphTemporalSql.d.ts.map +1 -0
- package/script/helpers/prepareGraphTemporalSql.js +161 -0
- package/script/helpers/prepareGraphTraversal.d.ts +19 -0
- package/script/helpers/prepareGraphTraversal.d.ts.map +1 -0
- package/script/helpers/prepareGraphTraversal.js +87 -0
- package/script/helpers/prepareNumericFeatures.d.ts +41 -0
- package/script/helpers/prepareNumericFeatures.d.ts.map +1 -0
- package/script/helpers/prepareNumericFeatures.js +217 -0
- package/script/helpers/prettyDuration.d.ts +14 -8
- package/script/helpers/prettyDuration.d.ts.map +1 -1
- package/script/helpers/prettyDuration.js +14 -8
- package/script/helpers/printTable.d.ts +18 -13
- package/script/helpers/printTable.d.ts.map +1 -1
- package/script/helpers/printTable.js +18 -13
- package/script/helpers/publishPreparedColumns.d.ts +37 -0
- package/script/helpers/publishPreparedColumns.d.ts.map +1 -0
- package/script/helpers/publishPreparedColumns.js +119 -0
- package/script/helpers/queryDB.d.ts +24 -13
- package/script/helpers/queryDB.d.ts.map +1 -1
- package/script/helpers/queryDB.js +24 -13
- package/script/helpers/queueAsyncBarrier.d.ts +12 -7
- package/script/helpers/queueAsyncBarrier.d.ts.map +1 -1
- package/script/helpers/queueAsyncBarrier.js +12 -7
- package/script/helpers/queueGraphResult.d.ts +18 -0
- package/script/helpers/queueGraphResult.d.ts.map +1 -0
- package/script/helpers/queueGraphResult.js +45 -0
- package/script/helpers/quoteIdentifier.d.ts +4 -3
- package/script/helpers/quoteIdentifier.d.ts.map +1 -1
- package/script/helpers/quoteIdentifier.js +4 -3
- package/script/helpers/quoteQualifiedIdentifier.d.ts +6 -4
- package/script/helpers/quoteQualifiedIdentifier.d.ts.map +1 -1
- package/script/helpers/quoteQualifiedIdentifier.js +6 -4
- package/script/helpers/runQuery.d.ts.map +1 -1
- package/script/helpers/runQuery.js +17 -3
- package/script/helpers/selectFuzzyReplacements.d.ts +11 -0
- package/script/helpers/selectFuzzyReplacements.d.ts.map +1 -0
- package/script/helpers/selectFuzzyReplacements.js +127 -0
- package/script/helpers/stabilizeCosineVectors.d.ts +14 -0
- package/script/helpers/stabilizeCosineVectors.d.ts.map +1 -0
- package/script/helpers/stabilizeCosineVectors.js +40 -0
- package/script/helpers/stringToArray.d.ts +4 -3
- package/script/helpers/stringToArray.d.ts.map +1 -1
- package/script/helpers/stringToArray.js +4 -3
- package/script/helpers/updateColumnsWithJS.d.ts +12 -6
- package/script/helpers/updateColumnsWithJS.d.ts.map +1 -1
- package/script/helpers/updateColumnsWithJS.js +12 -6
- package/script/helpers/validateGraphRouteResultSchema.d.ts +4 -0
- package/script/helpers/validateGraphRouteResultSchema.d.ts.map +1 -0
- package/script/helpers/validateGraphRouteResultSchema.js +19 -0
- package/script/helpers/validateGraphTemporalEvents.d.ts +7 -0
- package/script/helpers/validateGraphTemporalEvents.d.ts.map +1 -0
- package/script/helpers/validateGraphTemporalEvents.js +53 -0
- package/script/helpers/validateNumericalAnalysis.d.ts +10 -6
- package/script/helpers/validateNumericalAnalysis.d.ts.map +1 -1
- package/script/helpers/validateNumericalAnalysis.js +10 -6
- package/script/helpers/validateVectorRowIds.d.ts +4 -0
- package/script/helpers/validateVectorRowIds.d.ts.map +1 -0
- package/script/helpers/validateVectorRowIds.js +19 -0
- package/script/helpers/vectorDistanceExpression.d.ts +6 -0
- package/script/helpers/vectorDistanceExpression.d.ts.map +1 -0
- package/script/helpers/vectorDistanceExpression.js +14 -0
- package/script/helpers/wrapString.d.ts +10 -7
- package/script/helpers/wrapString.d.ts.map +1 -1
- package/script/helpers/wrapString.js +10 -7
- package/script/methods/addId.d.ts +5 -0
- package/script/methods/addId.d.ts.map +1 -0
- package/script/methods/addId.js +44 -0
- package/script/methods/commonNeighbors.d.ts +10 -0
- package/script/methods/commonNeighbors.d.ts.map +1 -0
- package/script/methods/commonNeighbors.js +140 -0
- package/script/methods/connectedComponents.d.ts +9 -0
- package/script/methods/connectedComponents.d.ts.map +1 -0
- package/script/methods/connectedComponents.js +186 -0
- package/script/methods/degree.d.ts +9 -0
- package/script/methods/degree.d.ts.map +1 -0
- package/script/methods/degree.js +141 -0
- package/script/methods/distances.d.ts +12 -0
- package/script/methods/distances.d.ts.map +1 -0
- package/script/methods/distances.js +203 -0
- package/script/methods/findCycles.d.ts +12 -0
- package/script/methods/findCycles.d.ts.map +1 -0
- package/script/methods/findCycles.js +369 -0
- package/script/methods/fuzzyClean.d.ts.map +1 -1
- package/script/methods/fuzzyClean.js +17 -136
- package/script/methods/fuzzyJoin.js +70 -16
- package/script/methods/getTypes.d.ts +1 -1
- package/script/methods/hdbscan.d.ts +5 -0
- package/script/methods/hdbscan.d.ts.map +1 -0
- package/script/methods/hdbscan.js +214 -0
- package/script/methods/mahalanobis.d.ts +5 -0
- package/script/methods/mahalanobis.d.ts.map +1 -0
- package/script/methods/mahalanobis.js +98 -0
- package/script/methods/neighbors.d.ts +9 -0
- package/script/methods/neighbors.d.ts.map +1 -0
- package/script/methods/neighbors.js +120 -0
- package/script/methods/normalizeVector.d.ts +5 -0
- package/script/methods/normalizeVector.d.ts.map +1 -0
- package/script/methods/normalizeVector.js +138 -0
- package/script/methods/paths.d.ts +12 -0
- package/script/methods/paths.d.ts.map +1 -0
- package/script/methods/paths.js +326 -0
- package/script/methods/reachable.d.ts +11 -0
- package/script/methods/reachable.d.ts.map +1 -0
- package/script/methods/reachable.js +170 -0
- package/script/methods/rowToVector.d.ts +5 -0
- package/script/methods/rowToVector.d.ts.map +1 -0
- package/script/methods/rowToVector.js +83 -0
- package/script/methods/shortestPath.d.ts +12 -0
- package/script/methods/shortestPath.d.ts.map +1 -0
- package/script/methods/shortestPath.js +376 -0
- package/script/methods/topologicalSort.d.ts +7 -0
- package/script/methods/topologicalSort.d.ts.map +1 -0
- package/script/methods/topologicalSort.js +170 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import getGraphEdgeIdColumn from "../helpers/getGraphEdgeIdColumn.js";
|
|
2
|
+
import getGraphWeightColumn from "../helpers/getGraphWeightColumn.js";
|
|
3
|
+
import graphRouteResultSchema from "../helpers/graphRouteResultSchema.js";
|
|
4
|
+
import graphRouteResultSelect from "../helpers/graphRouteResultSelect.js";
|
|
5
|
+
import prepareGraphTemporalSql, { prepareGraphTemporalOptions, } from "../helpers/prepareGraphTemporalSql.js";
|
|
6
|
+
import prepareGraphStarts from "../helpers/prepareGraphStarts.js";
|
|
7
|
+
import prepareGraphTraversal, { validateGraphStarts, } from "../helpers/prepareGraphTraversal.js";
|
|
8
|
+
import queueGraphResult from "../helpers/queueGraphResult.js";
|
|
9
|
+
import quoteIdentifier from "../helpers/quoteIdentifier.js";
|
|
10
|
+
import validateGraphTemporalEvents from "../helpers/validateGraphTemporalEvents.js";
|
|
11
|
+
import validateGraphRouteResultSchema from "../helpers/validateGraphRouteResultSchema.js";
|
|
12
|
+
export default function findCycles(simpleTable, sourceColumn, targetColumn, edgeId, startNodes, options = {}) {
|
|
13
|
+
if (typeof sourceColumn !== "string") {
|
|
14
|
+
throw new TypeError("findCycles() sourceColumn must be a string.");
|
|
15
|
+
}
|
|
16
|
+
if (typeof targetColumn !== "string") {
|
|
17
|
+
throw new TypeError("findCycles() targetColumn must be a string.");
|
|
18
|
+
}
|
|
19
|
+
if (typeof edgeId !== "string") {
|
|
20
|
+
throw new TypeError("findCycles() edgeId must be a string.");
|
|
21
|
+
}
|
|
22
|
+
const preparedStarts = prepareGraphStarts(startNodes, "findCycles()", "startNodes");
|
|
23
|
+
if (options === null || typeof options !== "object" || Array.isArray(options)) {
|
|
24
|
+
throw new TypeError("findCycles() options must be an object.");
|
|
25
|
+
}
|
|
26
|
+
if (options.direction !== undefined &&
|
|
27
|
+
!["outgoing", "incoming", "both"].includes(options.direction)) {
|
|
28
|
+
throw new TypeError('findCycles() options.direction must be "outgoing", "incoming", or "both".');
|
|
29
|
+
}
|
|
30
|
+
if (options.weight !== undefined && typeof options.weight !== "string") {
|
|
31
|
+
throw new TypeError("findCycles() options.weight must be a string.");
|
|
32
|
+
}
|
|
33
|
+
if (options.outputTable !== undefined &&
|
|
34
|
+
typeof options.outputTable !== "string" &&
|
|
35
|
+
typeof options.outputTable !== "boolean") {
|
|
36
|
+
throw new TypeError("findCycles() options.outputTable must be a string or boolean.");
|
|
37
|
+
}
|
|
38
|
+
const direction = options.direction ?? "outgoing";
|
|
39
|
+
const temporalOptions = prepareGraphTemporalOptions(options, direction, "findCycles()");
|
|
40
|
+
options = structuredClone(options);
|
|
41
|
+
const parameters = {
|
|
42
|
+
sourceColumn,
|
|
43
|
+
targetColumn,
|
|
44
|
+
edgeId,
|
|
45
|
+
startNodes: structuredClone(startNodes),
|
|
46
|
+
options,
|
|
47
|
+
};
|
|
48
|
+
return queueGraphResult(simpleTable, {
|
|
49
|
+
method: "findCycles()",
|
|
50
|
+
parameters,
|
|
51
|
+
outputTable: options.outputTable,
|
|
52
|
+
preflight: temporalOptions === undefined
|
|
53
|
+
? undefined
|
|
54
|
+
: (input) => validateGraphTemporalEvents(input, temporalOptions, "findCycles()", parameters),
|
|
55
|
+
values: (schema) => {
|
|
56
|
+
validateFindCyclesInputs(schema, sourceColumn, targetColumn, edgeId, preparedStarts, options.weight);
|
|
57
|
+
const temporal = temporalOptions === undefined
|
|
58
|
+
? undefined
|
|
59
|
+
: prepareGraphTemporalSql(schema, temporalOptions, "findCycles()");
|
|
60
|
+
return temporal === undefined
|
|
61
|
+
? preparedStarts.values
|
|
62
|
+
: [temporal.gapParameter, ...preparedStarts.values];
|
|
63
|
+
},
|
|
64
|
+
buildSelect: (input, schema) => findCyclesSelect(input, schema, sourceColumn, targetColumn, edgeId, preparedStarts, direction, options.weight, temporalOptions),
|
|
65
|
+
outputSchema: (schema) => {
|
|
66
|
+
const validated = validateFindCyclesInputs(schema, sourceColumn, targetColumn, edgeId, preparedStarts, options.weight);
|
|
67
|
+
if (temporalOptions !== undefined) {
|
|
68
|
+
prepareGraphTemporalSql(schema, temporalOptions, "findCycles()");
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
start: validated.nodeIdType,
|
|
72
|
+
...graphRouteResultSchema(schema, validated.distanceType, "findCycles()"),
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function validateFindCyclesInputs(schema, source, target, edgeId, starts, weight) {
|
|
78
|
+
const endpoints = validateGraphStarts(schema, source, target, starts, "findCycles()", "startNodes");
|
|
79
|
+
const edgeIdColumn = getGraphEdgeIdColumn(schema, edgeId, "findCycles()");
|
|
80
|
+
const weightColumn = weight === undefined
|
|
81
|
+
? undefined
|
|
82
|
+
: getGraphWeightColumn(schema, weight, "findCycles()");
|
|
83
|
+
validateGraphRouteResultSchema(schema, "findCycles()", ["start"]);
|
|
84
|
+
return {
|
|
85
|
+
distanceType: weightColumn?.distanceType ?? "BIGINT",
|
|
86
|
+
edgeIdType: edgeIdColumn.idType,
|
|
87
|
+
nodeIdType: endpoints.idType,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function findCyclesSelect(input, schema, source, target, edgeId, starts, direction, weight, temporalOptions) {
|
|
91
|
+
const prepared = prepareGraphTraversal(input, schema, source, target, starts, "findCycles()", "startNodes");
|
|
92
|
+
const edgeIdColumn = getGraphEdgeIdColumn(schema, edgeId, "findCycles()");
|
|
93
|
+
const weightColumn = weight === undefined
|
|
94
|
+
? undefined
|
|
95
|
+
: getGraphWeightColumn(schema, weight, "findCycles()");
|
|
96
|
+
const distanceType = weightColumn?.distanceType ?? "BIGINT";
|
|
97
|
+
const q = quoteIdentifier;
|
|
98
|
+
const edgeIdReference = `${q("edges")}.${q(edgeIdColumn.column)}`;
|
|
99
|
+
const typedEdgeId = `CAST(${edgeIdReference} AS ${edgeIdColumn.idType})`;
|
|
100
|
+
const edgeKey = edgeIdColumn.family === "string"
|
|
101
|
+
? `ENCODE(${typedEdgeId})`
|
|
102
|
+
: typedEdgeId;
|
|
103
|
+
const edgeWeight = weightColumn === undefined
|
|
104
|
+
? `CAST(1 AS ${distanceType})`
|
|
105
|
+
: `CAST(${q("edges")}.${q(weightColumn.column)} AS ${distanceType})`;
|
|
106
|
+
const stepType = `STRUCT(${q("edgeId")} ${edgeIdColumn.idType}, ${q("source")} ${prepared.endpoints.idType}, ${q("target")} ${prepared.endpoints.idType}, ${q("weight")} ${distanceType}, ${q("distance")} ${distanceType})`;
|
|
107
|
+
if (temporalOptions !== undefined) {
|
|
108
|
+
const temporal = prepareGraphTemporalSql(schema, temporalOptions, "findCycles()");
|
|
109
|
+
return temporalFindCyclesSelect(prepared, direction, temporal, typedEdgeId, edgeKey, edgeWeight, distanceType, stepType, input, edgeIdColumn);
|
|
110
|
+
}
|
|
111
|
+
const relations = prepared.relationNames([
|
|
112
|
+
"graph_start_values",
|
|
113
|
+
"graph_starts",
|
|
114
|
+
"graph_edges",
|
|
115
|
+
"graph_cycle_walks",
|
|
116
|
+
"graph_complete_cycles",
|
|
117
|
+
"graph_ranked_cycles",
|
|
118
|
+
]);
|
|
119
|
+
const startValuesRelation = relations.graph_start_values;
|
|
120
|
+
const startsRelation = relations.graph_starts;
|
|
121
|
+
const edgesRelation = relations.graph_edges;
|
|
122
|
+
const walksRelation = relations.graph_cycle_walks;
|
|
123
|
+
const completeRelation = relations.graph_complete_cycles;
|
|
124
|
+
const rankedRelation = relations.graph_ranked_cycles;
|
|
125
|
+
const edgeFrom = `${q("edges")}.${q("__from")}`;
|
|
126
|
+
const edgeTo = `${q("edges")}.${q("__to")}`;
|
|
127
|
+
const edgeFromKey = `${q("edges")}.${q("__from_key")}`;
|
|
128
|
+
const edgeToKey = `${q("edges")}.${q("__to_key")}`;
|
|
129
|
+
const edgeIdentity = `${q("edges")}.${q("__edge_id")}`;
|
|
130
|
+
const edgeIdentityKey = `${q("edges")}.${q("__edge_key")}`;
|
|
131
|
+
const edgeCost = `${q("edges")}.${q("__weight")}`;
|
|
132
|
+
const walkDistance = `${q("walks")}.${q("distance")}`;
|
|
133
|
+
const candidateDistance = `CAST(${walkDistance} + ${edgeCost} AS ${distanceType})`;
|
|
134
|
+
return `WITH RECURSIVE ${startValuesRelation}(${q("start")}) AS (
|
|
135
|
+
VALUES ${prepared.startValues}
|
|
136
|
+
), ${startsRelation} AS (
|
|
137
|
+
SELECT ${q("start")},
|
|
138
|
+
${prepared.key(q("start"))} AS ${q("__start_key")}
|
|
139
|
+
FROM ${startValuesRelation}
|
|
140
|
+
), ${edgesRelation} AS (
|
|
141
|
+
${prepared.edges(direction, [
|
|
142
|
+
`${typedEdgeId} AS ${q("__edge_id")}`,
|
|
143
|
+
`${edgeKey} AS ${q("__edge_key")}`,
|
|
144
|
+
`${edgeWeight} AS ${q("__weight")}`,
|
|
145
|
+
])}
|
|
146
|
+
), ${walksRelation}(
|
|
147
|
+
${q("start")}, ${q("__start_key")}, ${q("node")},
|
|
148
|
+
${q("__node_key")}, ${q("__visited")}, ${q("__edge_keys")},
|
|
149
|
+
${q("steps")}, ${q("distance")}, ${q("closed")}
|
|
150
|
+
) AS (
|
|
151
|
+
SELECT ${q("starts")}.${q("start")},
|
|
152
|
+
${q("starts")}.${q("__start_key")}, ${edgeTo}, ${edgeToKey},
|
|
153
|
+
CASE WHEN ${edgeFromKey} = ${edgeToKey}
|
|
154
|
+
THEN [${edgeFromKey}]
|
|
155
|
+
ELSE [${edgeFromKey}, ${edgeToKey}]
|
|
156
|
+
END,
|
|
157
|
+
[${edgeIdentityKey}],
|
|
158
|
+
[struct_pack(
|
|
159
|
+
${q("edgeId")} := ${edgeIdentity},
|
|
160
|
+
${q("source")} := ${edgeFrom},
|
|
161
|
+
${q("target")} := ${edgeTo},
|
|
162
|
+
${q("weight")} := ${edgeCost},
|
|
163
|
+
${q("distance")} := ${edgeCost}
|
|
164
|
+
)]::${stepType}[],
|
|
165
|
+
${edgeCost}, ${edgeFromKey} = ${edgeToKey}
|
|
166
|
+
FROM ${edgesRelation} AS ${q("edges")}
|
|
167
|
+
INNER JOIN ${startsRelation} AS ${q("starts")}
|
|
168
|
+
ON ${q("starts")}.${q("__start_key")} = ${edgeFromKey}
|
|
169
|
+
UNION ALL
|
|
170
|
+
SELECT ${q("walks")}.${q("start")},
|
|
171
|
+
${q("walks")}.${q("__start_key")}, ${edgeTo}, ${edgeToKey},
|
|
172
|
+
list_append(${q("walks")}.${q("__visited")}, ${edgeToKey}),
|
|
173
|
+
list_append(${q("walks")}.${q("__edge_keys")}, ${edgeIdentityKey}),
|
|
174
|
+
list_append(${q("walks")}.${q("steps")}, struct_pack(
|
|
175
|
+
${q("edgeId")} := ${edgeIdentity},
|
|
176
|
+
${q("source")} := ${edgeFrom},
|
|
177
|
+
${q("target")} := ${edgeTo},
|
|
178
|
+
${q("weight")} := ${edgeCost},
|
|
179
|
+
${q("distance")} := ${candidateDistance}
|
|
180
|
+
)), ${candidateDistance},
|
|
181
|
+
${edgeToKey} = ${q("walks")}.${q("__start_key")}
|
|
182
|
+
FROM ${walksRelation} AS ${q("walks")}
|
|
183
|
+
INNER JOIN ${edgesRelation} AS ${q("edges")}
|
|
184
|
+
ON ${q("walks")}.${q("__node_key")} = ${edgeFromKey}
|
|
185
|
+
WHERE NOT ${q("walks")}.${q("closed")}
|
|
186
|
+
AND NOT list_contains(
|
|
187
|
+
${q("walks")}.${q("__edge_keys")}, ${edgeIdentityKey}
|
|
188
|
+
)
|
|
189
|
+
AND (
|
|
190
|
+
${edgeToKey} = ${q("walks")}.${q("__start_key")}
|
|
191
|
+
OR NOT list_contains(
|
|
192
|
+
${q("walks")}.${q("__visited")}, ${edgeToKey}
|
|
193
|
+
)
|
|
194
|
+
)
|
|
195
|
+
), ${completeRelation} AS (
|
|
196
|
+
SELECT DISTINCT ${q("start")}, ${q("__start_key")},
|
|
197
|
+
${q("__edge_keys")}, ${q("steps")}
|
|
198
|
+
FROM ${walksRelation}
|
|
199
|
+
WHERE ${q("closed")}${direction === "both"
|
|
200
|
+
? `
|
|
201
|
+
AND ${q("__edge_keys")} <= list_reverse(${q("__edge_keys")})`
|
|
202
|
+
: ""}
|
|
203
|
+
), ${rankedRelation} AS (
|
|
204
|
+
SELECT ${q("start")}, ${q("__start_key")},
|
|
205
|
+
CAST(row_number() OVER (
|
|
206
|
+
PARTITION BY ${q("__start_key")}
|
|
207
|
+
ORDER BY ${q("__edge_keys")}) - 1
|
|
208
|
+
AS BIGINT) AS ${q("pathId")}, ${q("steps")}
|
|
209
|
+
FROM ${completeRelation}
|
|
210
|
+
)
|
|
211
|
+
${graphRouteResultSelect(rankedRelation, input, edgeIdColumn, true)}`;
|
|
212
|
+
}
|
|
213
|
+
function temporalFindCyclesSelect(prepared, direction, temporal, typedEdgeId, edgeKey, edgeWeight, distanceType, stepType, input, edgeIdColumn) {
|
|
214
|
+
const q = quoteIdentifier;
|
|
215
|
+
const relations = prepared.relationNames([
|
|
216
|
+
"graph_start_values",
|
|
217
|
+
"graph_starts",
|
|
218
|
+
"graph_temporal_settings",
|
|
219
|
+
"graph_event_rows",
|
|
220
|
+
"graph_edges",
|
|
221
|
+
"graph_cycle_walks",
|
|
222
|
+
"graph_complete_cycles",
|
|
223
|
+
"graph_ranked_cycles",
|
|
224
|
+
]);
|
|
225
|
+
const startValuesRelation = relations.graph_start_values;
|
|
226
|
+
const startsRelation = relations.graph_starts;
|
|
227
|
+
const settingsRelation = relations.graph_temporal_settings;
|
|
228
|
+
const eventRowsRelation = relations.graph_event_rows;
|
|
229
|
+
const edgesRelation = relations.graph_edges;
|
|
230
|
+
const walksRelation = relations.graph_cycle_walks;
|
|
231
|
+
const completeRelation = relations.graph_complete_cycles;
|
|
232
|
+
const rankedRelation = relations.graph_ranked_cycles;
|
|
233
|
+
const edgeFrom = `${q("edges")}.${q("__from")}`;
|
|
234
|
+
const edgeTo = `${q("edges")}.${q("__to")}`;
|
|
235
|
+
const edgeFromKey = `${q("edges")}.${q("__from_key")}`;
|
|
236
|
+
const edgeToKey = `${q("edges")}.${q("__to_key")}`;
|
|
237
|
+
const edgeIdentity = `${q("edges")}.${q("__edge_id")}`;
|
|
238
|
+
const edgeIdentityKey = `${q("edges")}.${q("__edge_key")}`;
|
|
239
|
+
const edgeCost = `${q("edges")}.${q("__weight")}`;
|
|
240
|
+
const walkDistance = `${q("walks")}.${q("distance")}`;
|
|
241
|
+
const candidateDistance = `CAST(${walkDistance} + ${edgeCost} AS ${distanceType})`;
|
|
242
|
+
const gap = `${q("settings")}.${q("__gap")}`;
|
|
243
|
+
const step = (distance) => `struct_pack(
|
|
244
|
+
${q("edgeId")} := ${edgeIdentity},
|
|
245
|
+
${q("source")} := ${edgeFrom},
|
|
246
|
+
${q("target")} := ${edgeTo},
|
|
247
|
+
${q("weight")} := ${edgeCost},
|
|
248
|
+
${q("distance")} := ${distance}
|
|
249
|
+
)`;
|
|
250
|
+
return `WITH RECURSIVE ${settingsRelation} AS MATERIALIZED (
|
|
251
|
+
SELECT CAST(? AS HUGEINT) AS ${q("__gap")}
|
|
252
|
+
), ${startValuesRelation}(${q("start")}) AS (
|
|
253
|
+
VALUES ${prepared.startValues}
|
|
254
|
+
), ${startsRelation} AS (
|
|
255
|
+
SELECT ${q("start")},
|
|
256
|
+
${prepared.key(q("start"))} AS ${q("__start_key")}
|
|
257
|
+
FROM ${startValuesRelation}
|
|
258
|
+
), ${eventRowsRelation} AS MATERIALIZED (
|
|
259
|
+
${prepared.edges(direction, [
|
|
260
|
+
`${typedEdgeId} AS ${q("__edge_id")}`,
|
|
261
|
+
`${edgeKey} AS ${q("__edge_key")}`,
|
|
262
|
+
`${edgeWeight} AS ${q("__weight")}`,
|
|
263
|
+
...temporal.eventSelections("edges"),
|
|
264
|
+
])}
|
|
265
|
+
), ${edgesRelation} AS MATERIALIZED (
|
|
266
|
+
SELECT *
|
|
267
|
+
FROM ${eventRowsRelation} AS ${q("events")}
|
|
268
|
+
WHERE ${temporal.eventValidity("events")}
|
|
269
|
+
), ${walksRelation}(
|
|
270
|
+
${q("start")}, ${q("__start_key")}, ${q("node")},
|
|
271
|
+
${q("__node_key")}, ${q("__visited")}, ${q("__event_ids")},
|
|
272
|
+
${q("__edge_keys")}, ${q("steps")}, ${q("distance")},
|
|
273
|
+
${q("closed")}, ${q("__event_id")}, ${q("__event_start")},
|
|
274
|
+
${q("__event_end")}
|
|
275
|
+
) AS (
|
|
276
|
+
SELECT ${q("starts")}.${q("start")},
|
|
277
|
+
${q("starts")}.${q("__start_key")}, ${edgeTo}, ${edgeToKey},
|
|
278
|
+
CASE WHEN ${edgeFromKey} = ${edgeToKey}
|
|
279
|
+
THEN [${edgeFromKey}]
|
|
280
|
+
ELSE [${edgeFromKey}, ${edgeToKey}]
|
|
281
|
+
END,
|
|
282
|
+
[${q("edges")}.${q("__event_id")}], [${edgeIdentityKey}],
|
|
283
|
+
[${step(edgeCost)}]::${stepType}[], ${edgeCost},
|
|
284
|
+
${edgeFromKey} = ${edgeToKey},
|
|
285
|
+
${q("edges")}.${q("__event_id")},
|
|
286
|
+
${q("edges")}.${q("__event_start")},
|
|
287
|
+
${q("edges")}.${q("__event_end")}
|
|
288
|
+
FROM ${edgesRelation} AS ${q("edges")}
|
|
289
|
+
INNER JOIN ${startsRelation} AS ${q("starts")}
|
|
290
|
+
ON ${q("starts")}.${q("__start_key")} = ${edgeFromKey}
|
|
291
|
+
UNION ALL
|
|
292
|
+
SELECT ${q("walks")}.${q("start")},
|
|
293
|
+
${q("walks")}.${q("__start_key")}, ${edgeTo}, ${edgeToKey},
|
|
294
|
+
list_append(${q("walks")}.${q("__visited")}, ${edgeToKey}),
|
|
295
|
+
list_append(${q("walks")}.${q("__event_ids")},
|
|
296
|
+
${q("edges")}.${q("__event_id")}),
|
|
297
|
+
list_append(${q("walks")}.${q("__edge_keys")}, ${edgeIdentityKey}),
|
|
298
|
+
list_append(${q("walks")}.${q("steps")}, ${step(candidateDistance)}),
|
|
299
|
+
${candidateDistance},
|
|
300
|
+
${edgeToKey} = ${q("walks")}.${q("__start_key")},
|
|
301
|
+
${q("edges")}.${q("__event_id")},
|
|
302
|
+
${q("edges")}.${q("__event_start")},
|
|
303
|
+
${q("edges")}.${q("__event_end")}
|
|
304
|
+
FROM ${walksRelation} AS ${q("walks")}
|
|
305
|
+
INNER JOIN ${edgesRelation} AS ${q("edges")}
|
|
306
|
+
ON ${q("walks")}.${q("__node_key")} = ${edgeFromKey}
|
|
307
|
+
CROSS JOIN ${settingsRelation} AS ${q("settings")}
|
|
308
|
+
WHERE NOT ${q("walks")}.${q("closed")}
|
|
309
|
+
AND NOT list_contains(${q("walks")}.${q("__event_ids")},
|
|
310
|
+
${q("edges")}.${q("__event_id")})
|
|
311
|
+
AND (
|
|
312
|
+
${edgeToKey} = ${q("walks")}.${q("__start_key")}
|
|
313
|
+
OR NOT list_contains(${q("walks")}.${q("__visited")}, ${edgeToKey})
|
|
314
|
+
)
|
|
315
|
+
AND ${temporal.transition("walks", "edges", direction, gap)}
|
|
316
|
+
), ${completeRelation} AS (
|
|
317
|
+
SELECT DISTINCT ${q("start")}, ${q("__start_key")},
|
|
318
|
+
${q("__edge_keys")}, ${q("steps")}
|
|
319
|
+
FROM ${walksRelation}
|
|
320
|
+
WHERE ${q("closed")}
|
|
321
|
+
), ${rankedRelation} AS (
|
|
322
|
+
SELECT ${q("start")}, ${q("__start_key")},
|
|
323
|
+
CAST(row_number() OVER (
|
|
324
|
+
PARTITION BY ${q("__start_key")}
|
|
325
|
+
ORDER BY ${q("__edge_keys")}) - 1
|
|
326
|
+
AS BIGINT) AS ${q("pathId")}, ${q("steps")}
|
|
327
|
+
FROM ${completeRelation}
|
|
328
|
+
)
|
|
329
|
+
${graphRouteResultSelect(rankedRelation, input, edgeIdColumn, true)}`;
|
|
330
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fuzzyClean.d.ts","sourceRoot":"","sources":["../../src/methods/fuzzyClean.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fuzzyClean.d.ts","sourceRoot":"","sources":["../../src/methods/fuzzyClean.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AASvD,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACP,MAAM,CAAC,EACH,OAAO,GACP,eAAe,GACf,kBAAkB,GAClB,iBAAiB,CAAC;IACtB,QAAQ,CAAC,EACL,YAAY,GACZ,eAAe,GACf,gBAAgB,GAChB,aAAa,GACb,UAAU,CAAC;IACf,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC3B,GACL,IAAI,CAWN"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import quoteIdentifier from "../helpers/quoteIdentifier.js";
|
|
2
|
+
import { DuckDBListValue } from "@duckdb/node-api";
|
|
2
3
|
import mergeOptions from "../helpers/mergeOptions.js";
|
|
3
4
|
import queryDB from "../helpers/queryDB.js";
|
|
4
5
|
import queueOp from "../helpers/queueOp.js";
|
|
5
6
|
import buildFuzzyMatchSql from "../helpers/buildFuzzyMatchSql.js";
|
|
7
|
+
import selectFuzzyReplacements from "../helpers/selectFuzzyReplacements.js";
|
|
6
8
|
export default function fuzzyClean(table, column, newColumn, threshold, options = {}) {
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// executes as a barrier.
|
|
9
|
+
// This implementation clusters fuzzy pairs in JS and writes the mapping
|
|
10
|
+
// back to DuckDB, so it executes as a barrier.
|
|
10
11
|
options = structuredClone(options);
|
|
11
12
|
queueOp(table, {
|
|
12
13
|
kind: "barrier",
|
|
@@ -57,149 +58,29 @@ async function executeFuzzyClean(table, column, newColumn, threshold, options =
|
|
|
57
58
|
}
|
|
58
59
|
return;
|
|
59
60
|
}
|
|
60
|
-
|
|
61
|
-
const countMap = new Map();
|
|
62
|
-
for (const { left_value, left_cnt, right_value, right_cnt } of pairs) {
|
|
63
|
-
countMap.set(left_value, Number(left_cnt));
|
|
64
|
-
countMap.set(right_value, Number(right_cnt));
|
|
65
|
-
}
|
|
66
|
-
// Union-Find — only over values that actually participate in a pair.
|
|
67
|
-
const parent = new Map();
|
|
68
|
-
const find = (x) => {
|
|
69
|
-
if (!parent.has(x))
|
|
70
|
-
parent.set(x, x);
|
|
71
|
-
if (parent.get(x) !== x)
|
|
72
|
-
parent.set(x, find(parent.get(x)));
|
|
73
|
-
return parent.get(x);
|
|
74
|
-
};
|
|
75
|
-
const union = (a, b) => {
|
|
76
|
-
const ra = find(a);
|
|
77
|
-
const rb = find(b);
|
|
78
|
-
if (ra !== rb)
|
|
79
|
-
parent.set(ra, rb);
|
|
80
|
-
};
|
|
81
|
-
for (const v of countMap.keys())
|
|
82
|
-
find(v);
|
|
83
|
-
for (const { left_value, right_value } of pairs) {
|
|
84
|
-
union(left_value, right_value);
|
|
85
|
-
}
|
|
86
|
-
// Group values by their cluster root.
|
|
87
|
-
const clusters = new Map();
|
|
88
|
-
for (const v of countMap.keys()) {
|
|
89
|
-
const root = find(v);
|
|
90
|
-
if (!clusters.has(root))
|
|
91
|
-
clusters.set(root, []);
|
|
92
|
-
clusters.get(root).push(v);
|
|
93
|
-
}
|
|
94
|
-
// Pick the canonical value for each cluster.
|
|
95
|
-
const replacement = new Map();
|
|
96
|
-
for (const members of clusters.values()) {
|
|
97
|
-
if (members.length === 1)
|
|
98
|
-
continue; // All pairs are already canonical — skip.
|
|
99
|
-
// Score sums and per-member max scores are computed lazily — only when
|
|
100
|
-
// actually needed as a primary criterion or tie-breaker.
|
|
101
|
-
//
|
|
102
|
-
// scoreSum: total similarity to all other cluster members (used by
|
|
103
|
-
// "mostCentral" as primary, and as tie-breaker for all strategies).
|
|
104
|
-
// scoreMax: highest single pairwise score (used by "maxScore" as primary).
|
|
105
|
-
let scoreSum = null;
|
|
106
|
-
const getScoreSum = () => {
|
|
107
|
-
if (scoreSum === null) {
|
|
108
|
-
scoreSum = new Map(members.map((m) => [m, 0]));
|
|
109
|
-
for (const { left_value, right_value, score } of pairs) {
|
|
110
|
-
if (scoreSum.has(left_value) && scoreSum.has(right_value)) {
|
|
111
|
-
scoreSum.set(left_value, (scoreSum.get(left_value) ?? 0) + score);
|
|
112
|
-
scoreSum.set(right_value, (scoreSum.get(right_value) ?? 0) + score);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return scoreSum;
|
|
117
|
-
};
|
|
118
|
-
let scoreMax = null;
|
|
119
|
-
const getScoreMax = () => {
|
|
120
|
-
if (scoreMax === null) {
|
|
121
|
-
scoreMax = new Map(members.map((m) => [m, 0]));
|
|
122
|
-
for (const { left_value, right_value, score } of pairs) {
|
|
123
|
-
if (scoreMax.has(left_value) && scoreMax.has(right_value)) {
|
|
124
|
-
scoreMax.set(left_value, Math.max(scoreMax.get(left_value) ?? 0, score));
|
|
125
|
-
scoreMax.set(right_value, Math.max(scoreMax.get(right_value) ?? 0, score));
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return scoreMax;
|
|
130
|
-
};
|
|
131
|
-
// Sum-based comparator: highest total similarity, then alphabetical.
|
|
132
|
-
const byScore = (a, b) => {
|
|
133
|
-
const sum = getScoreSum();
|
|
134
|
-
const sa = sum.get(a) ?? 0;
|
|
135
|
-
const sb = sum.get(b) ?? 0;
|
|
136
|
-
if (sa !== sb)
|
|
137
|
-
return sa > sb ? a : b;
|
|
138
|
-
return a <= b ? a : b; // alphabetical tie-break
|
|
139
|
-
};
|
|
140
|
-
// Max-based comparator: highest single-pair score, then sum, then alphabetical.
|
|
141
|
-
const byMaxScore = (a, b) => {
|
|
142
|
-
const mx = getScoreMax();
|
|
143
|
-
const ma = mx.get(a) ?? 0;
|
|
144
|
-
const mb = mx.get(b) ?? 0;
|
|
145
|
-
if (ma !== mb)
|
|
146
|
-
return ma > mb ? a : b;
|
|
147
|
-
return byScore(a, b); // sum then alphabetical tie-break
|
|
148
|
-
};
|
|
149
|
-
let canonical;
|
|
150
|
-
if (strategy === "longestString") {
|
|
151
|
-
canonical = members.reduce((a, b) => {
|
|
152
|
-
if (a.length !== b.length)
|
|
153
|
-
return a.length > b.length ? a : b;
|
|
154
|
-
return byScore(a, b);
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
else if (strategy === "shortestString") {
|
|
158
|
-
canonical = members.reduce((a, b) => {
|
|
159
|
-
if (a.length !== b.length)
|
|
160
|
-
return a.length < b.length ? a : b;
|
|
161
|
-
return byScore(a, b);
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
else if (strategy === "mostCommon") {
|
|
165
|
-
canonical = members.reduce((a, b) => {
|
|
166
|
-
const ca = countMap.get(a) ?? 0;
|
|
167
|
-
const cb = countMap.get(b) ?? 0;
|
|
168
|
-
if (ca !== cb)
|
|
169
|
-
return ca > cb ? a : b;
|
|
170
|
-
return byScore(a, b);
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
else if (strategy === "mostCentral") {
|
|
174
|
-
// Most central string — highest total similarity to all other cluster members.
|
|
175
|
-
canonical = members.reduce((a, b) => byScore(a, b));
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
// "maxScore": the string participating in the single highest-scoring pair.
|
|
179
|
-
canonical = members.reduce((a, b) => byMaxScore(a, b));
|
|
180
|
-
}
|
|
181
|
-
for (const m of members) {
|
|
182
|
-
if (m !== canonical)
|
|
183
|
-
replacement.set(m, canonical);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
61
|
+
const replacement = selectFuzzyReplacements(pairs, strategy);
|
|
186
62
|
if (replacement.size === 0)
|
|
187
63
|
return;
|
|
188
|
-
//
|
|
189
|
-
//
|
|
190
|
-
|
|
191
|
-
const
|
|
192
|
-
|
|
64
|
+
// Two bound lists keep the SQL and parameter count fixed as the mapping
|
|
65
|
+
// grows. Side-by-side UNNEST zips the equally sized lists into mapping rows,
|
|
66
|
+
// which DuckDB can hash-join to the original table.
|
|
67
|
+
const values = [
|
|
68
|
+
new DuckDBListValue([...replacement.keys()]),
|
|
69
|
+
new DuckDBListValue([...replacement.values()]),
|
|
70
|
+
];
|
|
71
|
+
const mapping = `WITH mapping(original, canonical) AS (
|
|
72
|
+
SELECT UNNEST(?::VARCHAR[]), UNNEST(?::VARCHAR[])
|
|
73
|
+
)`;
|
|
193
74
|
const query = newColumn !== column
|
|
194
75
|
? `ALTER TABLE ${quoteIdentifier(table.name)} ADD ${quoteIdentifier(newColumn)} VARCHAR;
|
|
195
76
|
UPDATE ${quoteIdentifier(table.name)}
|
|
196
77
|
SET ${quoteIdentifier(newColumn)} = ${quoteIdentifier(column)};
|
|
197
|
-
|
|
78
|
+
${mapping}
|
|
198
79
|
UPDATE ${quoteIdentifier(table.name)}
|
|
199
80
|
SET ${quoteIdentifier(newColumn)} = m.canonical
|
|
200
81
|
FROM mapping m
|
|
201
82
|
WHERE ${quoteIdentifier(table.name)}.${quoteIdentifier(newColumn)} = m.original`
|
|
202
|
-
:
|
|
83
|
+
: `${mapping}
|
|
203
84
|
UPDATE ${quoteIdentifier(table.name)}
|
|
204
85
|
SET ${quoteIdentifier(column)} = m.canonical
|
|
205
86
|
FROM mapping m
|
package/esm/methods/fuzzyJoin.js
CHANGED
|
@@ -48,17 +48,7 @@ async function executeFuzzyJoin(leftTable, rightTable, outputTable, leftColumn,
|
|
|
48
48
|
}
|
|
49
49
|
const method = options.method ?? "ratio";
|
|
50
50
|
const similarityColumn = options.similarityColumn;
|
|
51
|
-
|
|
52
|
-
// rightColumn can be shared, checked above) is excluded from the SELECT
|
|
53
|
-
// directly, instead of dropping its _1 duplicate with a rewrite after the
|
|
54
|
-
// join.
|
|
55
|
-
const rightSelect = rightCols
|
|
56
|
-
.filter((d) => !leftCols.includes(d))
|
|
57
|
-
.map((d) => `${quoteIdentifier(rightTable.name)}.${quoteIdentifier(d)}`)
|
|
58
|
-
.join(", ");
|
|
59
|
-
const sql = `INSTALL rapidfuzz FROM community; LOAD rapidfuzz;\n` +
|
|
60
|
-
fuzzyJoinQuery(leftTable.name, leftColumn, rightTable.name, rightColumn, method, threshold, outputTable.name, similarityColumn, rightSelect, options.prefilterPrefixLength);
|
|
61
|
-
await queryDB(leftTable, sql, mergeOptions(leftTable, {
|
|
51
|
+
const queryOptions = mergeOptions(leftTable, {
|
|
62
52
|
table: outputTable.name,
|
|
63
53
|
method: "fuzzyJoin()",
|
|
64
54
|
parameters: {
|
|
@@ -68,26 +58,90 @@ async function executeFuzzyJoin(leftTable, rightTable, outputTable, leftColumn,
|
|
|
68
58
|
threshold,
|
|
69
59
|
options,
|
|
70
60
|
},
|
|
71
|
-
})
|
|
61
|
+
});
|
|
62
|
+
const deduplicate = await shouldDeduplicateFuzzyJoin(leftTable, rightTable, leftColumn, rightColumn, queryOptions);
|
|
63
|
+
// The right table's copy of a column shared with the left table (only
|
|
64
|
+
// rightColumn can be shared, checked above) is excluded from the SELECT
|
|
65
|
+
// directly, instead of dropping its _1 duplicate with a rewrite after the
|
|
66
|
+
// join.
|
|
67
|
+
const rightSelect = rightCols
|
|
68
|
+
.filter((d) => !leftCols.includes(d))
|
|
69
|
+
.map((d) => `${quoteIdentifier(rightTable.name)}.${quoteIdentifier(d)}`)
|
|
70
|
+
.join(", ");
|
|
71
|
+
const sql = `INSTALL rapidfuzz FROM community; LOAD rapidfuzz;\n` +
|
|
72
|
+
fuzzyJoinQuery(leftTable.name, leftColumn, rightTable.name, rightColumn, method, threshold, outputTable.name, similarityColumn, rightSelect, options.prefilterPrefixLength, deduplicate);
|
|
73
|
+
await queryDB(leftTable, sql, queryOptions);
|
|
72
74
|
}
|
|
73
|
-
function
|
|
75
|
+
async function shouldDeduplicateFuzzyJoin(leftTable, rightTable, leftColumn, rightColumn, queryOptions) {
|
|
76
|
+
const left = quoteIdentifier(leftTable.name);
|
|
77
|
+
const right = quoteIdentifier(rightTable.name);
|
|
78
|
+
const counts = (await queryDB(leftTable, `SELECT (SELECT COUNT(*) FROM ${left}) AS left_count,
|
|
79
|
+
(SELECT COUNT(*) FROM ${right}) AS right_count`, { ...queryOptions, returnData: true }))[0];
|
|
80
|
+
const leftCount = Number(counts.left_count);
|
|
81
|
+
const rightCount = Number(counts.right_count);
|
|
82
|
+
const comparisons = leftCount * rightCount;
|
|
83
|
+
// Avoid distinct scans for small joins and short lookup tables. For larger
|
|
84
|
+
// joins, require at least a twofold reduction to pay for grouping and rejoining.
|
|
85
|
+
if (comparisons < 100_000 || Math.min(leftCount, rightCount) < 32) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
const distinct = (await queryDB(leftTable, `SELECT
|
|
89
|
+
(SELECT COUNT(DISTINCT ENCODE(${quoteIdentifier(leftColumn)})) FROM ${left}) AS left_count,
|
|
90
|
+
(SELECT COUNT(DISTINCT ENCODE(${quoteIdentifier(rightColumn)})) FROM ${right}) AS right_count`, { ...queryOptions, returnData: true }))[0];
|
|
91
|
+
return Number(distinct.left_count) * Number(distinct.right_count) <=
|
|
92
|
+
comparisons / 2;
|
|
93
|
+
}
|
|
94
|
+
function fuzzyJoinQuery(leftTable, leftColumn, rightTable, rightColumn, method, threshold, outputTable, similarityColumn, rightSelect, prefilterPrefixLength, deduplicate = false) {
|
|
74
95
|
const leftExpression = `${quoteIdentifier(leftTable)}.${quoteIdentifier(leftColumn)}`;
|
|
75
96
|
const rightExpression = `${quoteIdentifier(rightTable)}.${quoteIdentifier(rightColumn)}`;
|
|
76
97
|
const { scoreExpression, condition } = buildFuzzyMatchSql(leftExpression, rightExpression, method, threshold, { decimals: 2, prefilterPrefixLength });
|
|
98
|
+
let cte = "";
|
|
99
|
+
let from = `FROM ${quoteIdentifier(leftTable)} LEFT JOIN ${quoteIdentifier(rightTable)} ON ${condition}`;
|
|
100
|
+
let score = scoreExpression;
|
|
101
|
+
if (deduplicate) {
|
|
102
|
+
const matches = quoteIdentifier(`__sda_fuzzy_matches_${crypto.randomUUID().replaceAll("-", "")}`);
|
|
103
|
+
const match = buildFuzzyMatchSql("l.value", "r.value", method, threshold, { decimals: 2, prefilterPrefixLength });
|
|
104
|
+
// Keep the original value's collation for prefix matching, but use byte
|
|
105
|
+
// keys for deduplication and expansion: fuzzy scores distinguish case even
|
|
106
|
+
// when an input column has a case-insensitive collation.
|
|
107
|
+
cte = `WITH ${matches} AS MATERIALIZED (
|
|
108
|
+
SELECT l.key AS left_key, r.key AS right_key,
|
|
109
|
+
${match.scoreExpression} AS score
|
|
110
|
+
FROM (
|
|
111
|
+
SELECT DISTINCT ${quoteIdentifier(leftColumn)} AS value,
|
|
112
|
+
ENCODE(${quoteIdentifier(leftColumn)}) AS key
|
|
113
|
+
FROM ${quoteIdentifier(leftTable)}
|
|
114
|
+
WHERE ${quoteIdentifier(leftColumn)} IS NOT NULL
|
|
115
|
+
) l
|
|
116
|
+
INNER JOIN (
|
|
117
|
+
SELECT DISTINCT ${quoteIdentifier(rightColumn)} AS value,
|
|
118
|
+
ENCODE(${quoteIdentifier(rightColumn)}) AS key
|
|
119
|
+
FROM ${quoteIdentifier(rightTable)}
|
|
120
|
+
WHERE ${quoteIdentifier(rightColumn)} IS NOT NULL
|
|
121
|
+
) r ON ${match.condition}
|
|
122
|
+
)`;
|
|
123
|
+
from = `FROM ${quoteIdentifier(leftTable)}
|
|
124
|
+
LEFT JOIN ${matches} ON ENCODE(${leftExpression}) = ${matches}.left_key
|
|
125
|
+
LEFT JOIN ${quoteIdentifier(rightTable)}
|
|
126
|
+
ON ENCODE(${rightExpression}) = ${matches}.right_key`;
|
|
127
|
+
score = `${matches}.score`;
|
|
128
|
+
}
|
|
77
129
|
if (similarityColumn) {
|
|
78
130
|
return `CREATE OR REPLACE TABLE ${quoteIdentifier(outputTable)} AS
|
|
131
|
+
${cte}
|
|
79
132
|
SELECT * EXCLUDE ("_sda_score"), "_sda_score" AS ${quoteIdentifier(similarityColumn)}
|
|
80
133
|
FROM (
|
|
81
|
-
SELECT ${quoteIdentifier(leftTable)}.*, ${rightSelect}, ${
|
|
82
|
-
|
|
134
|
+
SELECT ${quoteIdentifier(leftTable)}.*, ${rightSelect}, ${score} AS "_sda_score"
|
|
135
|
+
${from}
|
|
83
136
|
) _sda
|
|
84
137
|
ORDER BY ${quoteIdentifier(leftColumn)}, "_sda_score" DESC;\n`;
|
|
85
138
|
}
|
|
86
139
|
return `CREATE OR REPLACE TABLE ${quoteIdentifier(outputTable)} AS
|
|
140
|
+
${cte}
|
|
87
141
|
SELECT *
|
|
88
142
|
FROM (
|
|
89
143
|
SELECT ${quoteIdentifier(leftTable)}.*, ${rightSelect}
|
|
90
|
-
|
|
144
|
+
${from}
|
|
91
145
|
) _sda
|
|
92
146
|
ORDER BY ${quoteIdentifier(leftColumn)}, ${quoteIdentifier(rightColumn)};\n`;
|
|
93
147
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type SimpleTable from "../class/SimpleTable.js";
|
|
2
|
+
type Options = NonNullable<Parameters<SimpleTable["hdbscan"]>[2]>;
|
|
3
|
+
export default function hdbscan(table: SimpleTable, columns: string | string[], newColumn: string, options?: Options): void;
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=hdbscan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hdbscan.d.ts","sourceRoot":"","sources":["../../src/methods/hdbscan.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAWvD,KAAK,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAElE,MAAM,CAAC,OAAO,UAAU,OAAO,CAC7B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAC1B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,OAAY,GACpB,IAAI,CASN"}
|