mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
merge-up for dapi and qdrant prototypes
This commit is contained in:
15
.run/SCENARIO astra DAPI dapi_novector.run.xml
Normal file
15
.run/SCENARIO astra DAPI dapi_novector.run.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="SCENARIO astra DAPI dapi_novector" type="JarApplication" folderName="Astra DAPI">
|
||||
<extension name="software.aws.toolkits.jetbrains.core.execution.JavaAwsConnectionExtension">
|
||||
<option name="credential" />
|
||||
<option name="region" />
|
||||
<option name="useCurrentConnection" value="false" />
|
||||
</extension>
|
||||
<option name="JAR_PATH" value="$PROJECT_DIR$/nb5/target/nb5.jar" />
|
||||
<option name="PROGRAM_PARAMETERS" value="astra_kv_dapi dapi_novector collection=baselines astraTokenFile=target/token astraApiEndpointFile=target/endpoint -v" />
|
||||
<option name="WORKING_DIRECTORY" value="$ProjectFileDir$/local/dataapi" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="21" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
15
.run/astra DAPI rampup threads=1.run.xml
Normal file
15
.run/astra DAPI rampup threads=1.run.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="astra DAPI rampup threads=1" type="JarApplication" folderName="Astra DAPI">
|
||||
<extension name="software.aws.toolkits.jetbrains.core.execution.JavaAwsConnectionExtension">
|
||||
<option name="credential" />
|
||||
<option name="region" />
|
||||
<option name="useCurrentConnection" value="false" />
|
||||
</extension>
|
||||
<option name="JAR_PATH" value="$PROJECT_DIR$/nb5/target/nb5.jar" />
|
||||
<option name="PROGRAM_PARAMETERS" value="astra_kv_dapi default.rampup threads=1 astraTokenFile=target/token astraApiEndpointFile=target/endpoint -v" />
|
||||
<option name="WORKING_DIRECTORY" value="$ProjectFileDir$/local/dataapi" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="21" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
15
.run/astra DAPI read.run.xml
Normal file
15
.run/astra DAPI read.run.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="astra DAPI read" type="JarApplication" folderName="Astra DAPI">
|
||||
<extension name="software.aws.toolkits.jetbrains.core.execution.JavaAwsConnectionExtension">
|
||||
<option name="credential" />
|
||||
<option name="region" />
|
||||
<option name="useCurrentConnection" value="false" />
|
||||
</extension>
|
||||
<option name="JAR_PATH" value="$PROJECT_DIR$/nb5/target/nb5.jar" />
|
||||
<option name="PROGRAM_PARAMETERS" value="astra_kv_dapi default.read threads=1 astraTokenFile=target/token astraApiEndpointFile=target/endpoint -v" />
|
||||
<option name="WORKING_DIRECTORY" value="$ProjectFileDir$/local/dataapi" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="21" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
0
nb-adapters/adapter-dataapi/README.md
Normal file
0
nb-adapters/adapter-dataapi/README.md
Normal file
57
nb-adapters/adapter-dataapi/pom.xml
Normal file
57
nb-adapters/adapter-dataapi/pom.xml
Normal file
@@ -0,0 +1,57 @@
|
||||
<!--
|
||||
~ Copyright (c) 2022-2023 nosqlbench
|
||||
~
|
||||
~ 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.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<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>
|
||||
|
||||
<artifactId>adapter-dataapi</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<artifactId>mvn-defaults</artifactId>
|
||||
<groupId>io.nosqlbench</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../mvn-defaults</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
An nosqlbench adapter driver module for the DataStax Data API
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.nosqlbench</groupId>
|
||||
<artifactId>nb-annotations</artifactId>
|
||||
<version>${revision}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.nosqlbench</groupId>
|
||||
<artifactId>adapters-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.datastax.astra</groupId>
|
||||
<artifactId>astra-db-java</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi;
|
||||
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapters.api.activityimpl.OpMapper;
|
||||
import io.nosqlbench.adapters.api.activityimpl.uniform.BaseDriverAdapter;
|
||||
import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter;
|
||||
import io.nosqlbench.nb.annotations.Service;
|
||||
import io.nosqlbench.nb.api.components.core.NBComponent;
|
||||
import io.nosqlbench.nb.api.config.standard.NBConfigModel;
|
||||
import io.nosqlbench.nb.api.config.standard.NBConfiguration;
|
||||
import io.nosqlbench.nb.api.labels.NBLabels;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@Service(value = DriverAdapter.class, selector = "dataapi")
|
||||
public class DataApiDriverAdapter extends BaseDriverAdapter<DataApiBaseOp, DataApiSpace> {
|
||||
public DataApiDriverAdapter(NBComponent parent, NBLabels childLabels) {
|
||||
super(parent, childLabels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpMapper getOpMapper() {
|
||||
return new DataApiOpMapper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<String, ? extends DataApiSpace> getSpaceInitializer(NBConfiguration cfg) {
|
||||
return (s) -> new DataApiSpace(s, cfg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBConfigModel getConfigModel() {
|
||||
return super.getConfigModel().add(DataApiSpace.getConfigModel());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi;
|
||||
|
||||
import io.nosqlbench.adapter.diag.DriverAdapterLoader;
|
||||
import io.nosqlbench.nb.annotations.Service;
|
||||
import io.nosqlbench.nb.api.components.core.NBComponent;
|
||||
import io.nosqlbench.nb.api.labels.NBLabels;
|
||||
|
||||
@Service(value = DriverAdapterLoader.class, selector = "dataapi")
|
||||
public class DataApiDriverAdapterLoader implements DriverAdapterLoader {
|
||||
@Override
|
||||
public DataApiDriverAdapter load(NBComponent parent, NBLabels childLabels) {
|
||||
return new DataApiDriverAdapter(parent, childLabels);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Filter;
|
||||
import com.datastax.astra.client.model.FindOptions;
|
||||
import com.datastax.astra.client.model.Projection;
|
||||
import com.datastax.astra.client.model.Sort;
|
||||
import io.nosqlbench.adapter.dataapi.opdispensers.DataApiOpDispenser;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiFindVectorFilterOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiFindVectorFilterOpDispenser extends DataApiOpDispenser {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiFindVectorFilterOpDispenser.class);
|
||||
private final LongFunction<DataApiFindVectorFilterOp> opFunction;
|
||||
public DataApiFindVectorFilterOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
this.opFunction = createOpFunction(op);
|
||||
}
|
||||
|
||||
private LongFunction<DataApiFindVectorFilterOp> createOpFunction(ParsedOp op) {
|
||||
return (l) -> {
|
||||
Database db = spaceFunction.apply(l).getDatabase();
|
||||
float[] vector = getVectorValues(op, l);
|
||||
Filter filter = getFilterFromOp(op, l);
|
||||
int limit = getLimit(op, l);
|
||||
return new DataApiFindVectorFilterOp(
|
||||
db,
|
||||
db.getCollection(targetFunction.apply(l)),
|
||||
vector,
|
||||
limit,
|
||||
filter
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private int getLimit(ParsedOp op, long l) {
|
||||
return op.getConfigOr("limit", 100, l);
|
||||
}
|
||||
|
||||
private FindOptions getFindOptions(ParsedOp op, long l) {
|
||||
FindOptions options = new FindOptions();
|
||||
Sort sort = getSortFromOp(op, l);
|
||||
float[] vector = getVectorValues(op, l);
|
||||
if (sort != null) {
|
||||
options = vector != null ? options.sort(vector, sort) : options.sort(sort);
|
||||
} else if (vector != null) {
|
||||
options = options.sort(vector);
|
||||
}
|
||||
Projection[] projection = getProjectionFromOp(op, l);
|
||||
if (projection != null) {
|
||||
options = options.projection(projection);
|
||||
}
|
||||
options.setIncludeSimilarity(true);
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return opFunction.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi;
|
||||
|
||||
import io.nosqlbench.adapter.dataapi.opdispensers.*;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiOpType;
|
||||
import io.nosqlbench.adapters.api.activityimpl.OpDispenser;
|
||||
import io.nosqlbench.adapters.api.activityimpl.OpMapper;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import io.nosqlbench.engine.api.templating.TypeAndTarget;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
public class DataApiOpMapper implements OpMapper<DataApiBaseOp> {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiOpMapper.class);
|
||||
private final DataApiDriverAdapter adapter;
|
||||
|
||||
public DataApiOpMapper(DataApiDriverAdapter dataApiDriverAdapter) {
|
||||
this.adapter = dataApiDriverAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpDispenser<? extends DataApiBaseOp> apply(ParsedOp op) {
|
||||
TypeAndTarget<DataApiOpType, String> typeAndTarget = op.getTypeAndTarget(
|
||||
DataApiOpType.class,
|
||||
String.class,
|
||||
"type",
|
||||
"collection"
|
||||
);
|
||||
logger.debug(() -> "Using '" + typeAndTarget.enumId + "' op type for op template '" + op.getName() + "'");
|
||||
return switch (typeAndTarget.enumId) {
|
||||
case create_collection -> new DataApiCreateCollectionOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case insert_many -> new DataApiInsertManyOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case insert_one -> new DataApiInsertOneOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case insert_one_vector -> new DataApiInsertOneVectorOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case find -> new DataApiFindOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case find_one -> new DataApiFindOneOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case find_one_and_delete -> new DataApiFindOneAndDeleteOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case find_one_and_update -> new DataApiFindOneAndUpdateOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case find_vector -> new DataApiFindVectorOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case find_vector_filter -> new DataApiFindVectorFilterOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case update_one -> new DataApiUpdateOneOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case update_many -> new DataApiUpdateManyOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case delete_one -> new DataApiDeleteOneOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case delete_many -> new DataApiDeleteManyOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
case delete_collection -> new DataApiDropCollectionOpDispenser(adapter, op, typeAndTarget.targetFunction);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi;
|
||||
|
||||
import com.datastax.astra.client.DataAPIClient;
|
||||
import com.datastax.astra.client.Database;
|
||||
import io.nosqlbench.nb.api.config.standard.ConfigModel;
|
||||
import io.nosqlbench.nb.api.config.standard.NBConfigModel;
|
||||
import io.nosqlbench.nb.api.config.standard.NBConfiguration;
|
||||
import io.nosqlbench.nb.api.config.standard.Param;
|
||||
import io.nosqlbench.nb.api.errors.BasicError;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
|
||||
public class DataApiSpace {
|
||||
private final static Logger logger = LogManager.getLogger(DataApiSpace.class);
|
||||
private final NBConfiguration config;
|
||||
private final String name;
|
||||
private String astraToken;
|
||||
private String astraApiEndpoint;
|
||||
private DataAPIClient dataAPIClient;
|
||||
private Database database;
|
||||
private String namespace;
|
||||
|
||||
public DataApiSpace(String name, NBConfiguration cfg) {
|
||||
this.config = cfg;
|
||||
this.name = name;
|
||||
setToken();
|
||||
setApiEndpoint();
|
||||
setNamespace();
|
||||
createClient();
|
||||
}
|
||||
|
||||
public DataAPIClient getDataAPIClient() {
|
||||
return dataAPIClient;
|
||||
}
|
||||
|
||||
public Database getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
private void createClient() {
|
||||
this.dataAPIClient = new DataAPIClient(astraToken);
|
||||
if (namespace != null) {
|
||||
this.database = dataAPIClient.getDatabase(astraApiEndpoint, namespace);
|
||||
} else {
|
||||
this.database = dataAPIClient.getDatabase(astraApiEndpoint);
|
||||
}
|
||||
}
|
||||
|
||||
private void setApiEndpoint() {
|
||||
Optional<String> epConfig = config.getOptional("astraApiEndpoint");
|
||||
Optional<String> epFileConfig = config.getOptional("astraApiEndpointFile");
|
||||
if (epConfig.isPresent() && epFileConfig.isPresent()) {
|
||||
throw new BasicError("You can only configure one of astraApiEndpoint or astraApiEndpointFile");
|
||||
}
|
||||
if (epConfig.isEmpty() && epFileConfig.isEmpty()) {
|
||||
throw new BasicError("You must configure one of astraApiEndpoint or astraApiEndpointFile");
|
||||
}
|
||||
epFileConfig
|
||||
.map(Path::of)
|
||||
.map(p -> {
|
||||
try {
|
||||
return Files.readString(p);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
})
|
||||
.map(String::trim)
|
||||
.ifPresent(ep -> this.astraApiEndpoint = ep);
|
||||
epConfig.ifPresent(ep -> this.astraApiEndpoint = ep);
|
||||
}
|
||||
|
||||
private void setNamespace() {
|
||||
Optional<String> maybeNamespace = config.getOptional("namespace");
|
||||
maybeNamespace.ifPresent(s -> this.namespace = s);
|
||||
}
|
||||
|
||||
private void setToken() {
|
||||
String tokenFileContents = null;
|
||||
Optional<String> tokenFilePath = config.getOptional("astraTokenFile");
|
||||
if (tokenFilePath.isPresent()) {
|
||||
Path path = Paths.get(tokenFilePath.get());
|
||||
try {
|
||||
tokenFileContents = Files.readAllLines(path).getFirst();
|
||||
} catch (IOException e) {
|
||||
String error = "Error while reading token from file:" + path;
|
||||
logger.error(error, e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
this.astraToken = (tokenFileContents != null) ? tokenFileContents : config.get("astraToken");
|
||||
}
|
||||
|
||||
public static NBConfigModel getConfigModel() {
|
||||
return ConfigModel.of(DataApiSpace.class)
|
||||
.add(
|
||||
Param.optional("astraTokenFile", String.class)
|
||||
.setDescription("file to load the Astra token from")
|
||||
)
|
||||
.add(
|
||||
Param.optional("astraToken", String.class)
|
||||
.setDescription("the Astra token used to connect to the database")
|
||||
)
|
||||
.add(
|
||||
Param.optional("astraApiEndpoint", String.class)
|
||||
.setDescription("the API endpoint for the Astra database")
|
||||
)
|
||||
.add(
|
||||
Param.optional("astraApiEndpointFile", String.class)
|
||||
.setDescription("file to load the API endpoint for the Astra database")
|
||||
)
|
||||
|
||||
.add(
|
||||
Param.defaultTo("namespace", "default_namespace")
|
||||
.setDescription("The Astra namespace to use")
|
||||
|
||||
)
|
||||
.asReadOnly();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import com.datastax.astra.client.model.CollectionOptions;
|
||||
import com.datastax.astra.client.model.SimilarityMetric;
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiCreateCollectionOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiCreateCollectionOpDispenser extends DataApiOpDispenser {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiCreateCollectionOpDispenser.class);
|
||||
private final LongFunction<DataApiCreateCollectionOp> opFunction;
|
||||
|
||||
public DataApiCreateCollectionOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
this.opFunction = createOpFunction(op);
|
||||
}
|
||||
|
||||
private LongFunction<DataApiCreateCollectionOp> createOpFunction(ParsedOp op) {
|
||||
return (l) -> {
|
||||
CollectionOptions.CollectionOptionsBuilder optionsBldr = CollectionOptions.builder();
|
||||
Optional<LongFunction<Integer>> dimFunc = op.getAsOptionalFunction("dimensions", Integer.class);
|
||||
if (dimFunc.isPresent()) {
|
||||
LongFunction<Integer> af = dimFunc.get();
|
||||
optionsBldr.vectorDimension(af.apply(l));
|
||||
}
|
||||
// COSINE("cosine"),
|
||||
// EUCLIDEAN("euclidean"),
|
||||
// DOT_PRODUCT("dot_product");
|
||||
Optional<LongFunction<String>> simFunc = op.getAsOptionalFunction("similarity", String.class);
|
||||
if (simFunc.isPresent()) {
|
||||
LongFunction<String> sf = simFunc.get();
|
||||
optionsBldr.vectorSimilarity(SimilarityMetric.fromValue(sf.apply(l)));
|
||||
}
|
||||
|
||||
DataApiCreateCollectionOp dataApiCreateCollectionOp =
|
||||
new DataApiCreateCollectionOp(
|
||||
spaceFunction.apply(l).getDatabase(),
|
||||
targetFunction.apply(l),
|
||||
optionsBldr.build());
|
||||
|
||||
return dataApiCreateCollectionOp;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return opFunction.apply(value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Filter;
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiDeleteManyOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiDeleteManyOpDispenser extends DataApiOpDispenser {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiDeleteManyOpDispenser.class);
|
||||
private final LongFunction<DataApiDeleteManyOp> opFunction;
|
||||
|
||||
public DataApiDeleteManyOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
this.opFunction = createOpFunction(op);
|
||||
}
|
||||
|
||||
private LongFunction<DataApiDeleteManyOp> createOpFunction(ParsedOp op) {
|
||||
return (l) -> {
|
||||
Database db = spaceFunction.apply(l).getDatabase();
|
||||
Filter filter = getFilterFromOp(op, l);
|
||||
|
||||
return new DataApiDeleteManyOp(
|
||||
db,
|
||||
db.getCollection(targetFunction.apply(l)),
|
||||
filter
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return opFunction.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.DeleteOneOptions;
|
||||
import com.datastax.astra.client.model.Filter;
|
||||
import com.datastax.astra.client.model.Sort;
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiDeleteOneOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiDeleteOneOpDispenser extends DataApiOpDispenser {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiDeleteOneOpDispenser.class);
|
||||
private final LongFunction<DataApiDeleteOneOp> opFunction;
|
||||
|
||||
public DataApiDeleteOneOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
this.opFunction = createOpFunction(op);
|
||||
}
|
||||
|
||||
private LongFunction<DataApiDeleteOneOp> createOpFunction(ParsedOp op) {
|
||||
return (l) -> {
|
||||
Database db = spaceFunction.apply(l).getDatabase();
|
||||
Filter filter = getFilterFromOp(op, l);
|
||||
DeleteOneOptions options = getDeleteOneOptions(op, l);
|
||||
|
||||
return new DataApiDeleteOneOp(
|
||||
db,
|
||||
db.getCollection(targetFunction.apply(l)),
|
||||
filter,
|
||||
options
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private DeleteOneOptions getDeleteOneOptions(ParsedOp op, long l) {
|
||||
DeleteOneOptions options = new DeleteOneOptions();
|
||||
Sort sort = getSortFromOp(op, l);
|
||||
if (sort != null) {
|
||||
options = options.sort(sort);
|
||||
}
|
||||
float[] vector = getVectorFromOp(op, l);
|
||||
if (vector != null) {
|
||||
options = options.vector(vector);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
private float[] getVectorFromOp(ParsedOp op, long l) {
|
||||
return getVectorValues(op.get("vector", l));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return opFunction.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiDropCollectionOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiDropCollectionOpDispenser extends DataApiOpDispenser {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiDropCollectionOpDispenser.class);
|
||||
private final LongFunction<DataApiDropCollectionOp> opFunction;
|
||||
public DataApiDropCollectionOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
this.opFunction = createOpFunction(op);
|
||||
}
|
||||
|
||||
private LongFunction<DataApiDropCollectionOp> createOpFunction(ParsedOp op) {
|
||||
return (l) -> new DataApiDropCollectionOp(
|
||||
spaceFunction.apply(l).getDatabase(),
|
||||
targetFunction.apply(l)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return opFunction.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Filter;
|
||||
import com.datastax.astra.client.model.FindOneAndDeleteOptions;
|
||||
import com.datastax.astra.client.model.Projection;
|
||||
import com.datastax.astra.client.model.Sort;
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiFindOneAndDeleteOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiFindOneAndDeleteOpDispenser extends DataApiOpDispenser {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiFindOneAndDeleteOpDispenser.class);
|
||||
private final LongFunction<DataApiFindOneAndDeleteOp> opFunction;
|
||||
|
||||
public DataApiFindOneAndDeleteOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
this.opFunction = createOpFunction(op);
|
||||
}
|
||||
|
||||
private LongFunction<DataApiFindOneAndDeleteOp> createOpFunction(ParsedOp op) {
|
||||
return (l) -> {
|
||||
Database db = spaceFunction.apply(l).getDatabase();
|
||||
Filter filter = getFilterFromOp(op, l);
|
||||
FindOneAndDeleteOptions options = getFindOneAndDeleteOptions(op, l);
|
||||
|
||||
return new DataApiFindOneAndDeleteOp(
|
||||
db,
|
||||
db.getCollection(targetFunction.apply(l)),
|
||||
filter,
|
||||
options
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private FindOneAndDeleteOptions getFindOneAndDeleteOptions(ParsedOp op, long l) {
|
||||
FindOneAndDeleteOptions options = new FindOneAndDeleteOptions();
|
||||
Sort sort = getSortFromOp(op, l);
|
||||
if (sort != null) {
|
||||
options = options.sort(sort);
|
||||
}
|
||||
Projection[] projection = getProjectionFromOp(op, l);
|
||||
if (projection != null) {
|
||||
options = options.projection(projection);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return opFunction.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Filter;
|
||||
import com.datastax.astra.client.model.Update;
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiFindOneAndUpdateOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiFindOneAndUpdateOpDispenser extends DataApiOpDispenser {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiFindOneAndUpdateOpDispenser.class);
|
||||
private final LongFunction<DataApiFindOneAndUpdateOp> opFunction;
|
||||
public DataApiFindOneAndUpdateOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
this.opFunction = createOpFunction(op);
|
||||
}
|
||||
|
||||
private LongFunction<DataApiFindOneAndUpdateOp> createOpFunction(ParsedOp op) {
|
||||
return (l) -> {
|
||||
Database db = spaceFunction.apply(l).getDatabase();
|
||||
Filter filter = getFilterFromOp(op, l);
|
||||
Update update = getUpdates(op, l);
|
||||
|
||||
return new DataApiFindOneAndUpdateOp(
|
||||
db,
|
||||
db.getCollection(targetFunction.apply(l)),
|
||||
filter,
|
||||
update
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return opFunction.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Filter;
|
||||
import com.datastax.astra.client.model.FindOneOptions;
|
||||
import com.datastax.astra.client.model.Projection;
|
||||
import com.datastax.astra.client.model.Sort;
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiFindOneOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiFindOneOpDispenser extends DataApiOpDispenser {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiFindOneOpDispenser.class);
|
||||
private final LongFunction<DataApiFindOneOp> opFunction;
|
||||
public DataApiFindOneOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
this.opFunction = createOpFunction(op);
|
||||
}
|
||||
|
||||
private LongFunction<DataApiFindOneOp> createOpFunction(ParsedOp op) {
|
||||
return (l) -> {
|
||||
Database db = spaceFunction.apply(l).getDatabase();
|
||||
Filter filter = getFilterFromOp(op, l);
|
||||
FindOneOptions options = getFindOneOptions(op, l);
|
||||
return new DataApiFindOneOp(
|
||||
db,
|
||||
db.getCollection(targetFunction.apply(l)),
|
||||
filter,
|
||||
options
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private FindOneOptions getFindOneOptions(ParsedOp op, long l) {
|
||||
FindOneOptions options = new FindOneOptions();
|
||||
Sort sort = getSortFromOp(op, l);
|
||||
float[] vector = getVectorValues(op, l);
|
||||
if (sort != null) {
|
||||
options = vector != null ? options.sort(vector, sort) : options.sort(sort);
|
||||
} else if (vector != null) {
|
||||
options = options.sort(vector);
|
||||
}
|
||||
Projection[] projection = getProjectionFromOp(op, l);
|
||||
if (projection != null) {
|
||||
options = options.projection(projection);
|
||||
}
|
||||
options.setIncludeSimilarity(true);
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return opFunction.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Filter;
|
||||
import com.datastax.astra.client.model.FindOptions;
|
||||
import com.datastax.astra.client.model.Projection;
|
||||
import com.datastax.astra.client.model.Sort;
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiFindOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiFindOpDispenser extends DataApiOpDispenser {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiFindOpDispenser.class);
|
||||
private final LongFunction<DataApiFindOp> opFunction;
|
||||
public DataApiFindOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
this.opFunction = createOpFunction(op);
|
||||
}
|
||||
|
||||
private LongFunction<DataApiFindOp> createOpFunction(ParsedOp op) {
|
||||
return (l) -> {
|
||||
Database db = spaceFunction.apply(l).getDatabase();
|
||||
Filter filter = getFilterFromOp(op, l);
|
||||
FindOptions options = getFindOptions(op, l);
|
||||
return new DataApiFindOp(
|
||||
db,
|
||||
db.getCollection(targetFunction.apply(l)),
|
||||
filter,
|
||||
options
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private FindOptions getFindOptions(ParsedOp op, long l) {
|
||||
FindOptions options = new FindOptions();
|
||||
Sort sort = getSortFromOp(op, l);
|
||||
if (op.isDefined("vector")) {
|
||||
float[] vector = getVectorValues(op, l);
|
||||
if (sort != null) {
|
||||
options = vector != null ? options.sort(vector, sort) : options.sort(sort);
|
||||
} else if (vector != null) {
|
||||
options = options.sort(vector);
|
||||
}
|
||||
}
|
||||
Projection[] projection = getProjectionFromOp(op, l);
|
||||
if (projection != null) {
|
||||
options = options.projection(projection);
|
||||
}
|
||||
options.setIncludeSimilarity(true);
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return opFunction.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.FindOptions;
|
||||
import com.datastax.astra.client.model.Projection;
|
||||
import com.datastax.astra.client.model.Sort;
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiFindVectorOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiFindVectorOpDispenser extends DataApiOpDispenser {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiFindVectorOpDispenser.class);
|
||||
private final LongFunction<DataApiFindVectorOp> opFunction;
|
||||
public DataApiFindVectorOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
this.opFunction = createOpFunction(op);
|
||||
}
|
||||
|
||||
private LongFunction<DataApiFindVectorOp> createOpFunction(ParsedOp op) {
|
||||
return (l) -> {
|
||||
Database db = spaceFunction.apply(l).getDatabase();
|
||||
float[] vector = getVectorValues(op, l);
|
||||
int limit = getLimit(op, l);
|
||||
return new DataApiFindVectorOp(
|
||||
db,
|
||||
db.getCollection(targetFunction.apply(l)),
|
||||
vector,
|
||||
limit
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private int getLimit(ParsedOp op, long l) {
|
||||
return op.getConfigOr("limit", 100, l);
|
||||
}
|
||||
|
||||
private FindOptions getFindOptions(ParsedOp op, long l) {
|
||||
FindOptions options = new FindOptions();
|
||||
Sort sort = getSortFromOp(op, l);
|
||||
float[] vector = getVectorValues(op, l);
|
||||
if (sort != null) {
|
||||
options = vector != null ? options.sort(vector, sort) : options.sort(sort);
|
||||
} else if (vector != null) {
|
||||
options = options.sort(vector);
|
||||
}
|
||||
Projection[] projection = getProjectionFromOp(op, l);
|
||||
if (projection != null) {
|
||||
options = options.projection(projection);
|
||||
}
|
||||
options.setIncludeSimilarity(true);
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return opFunction.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import com.datastax.astra.client.model.Document;
|
||||
import com.datastax.astra.client.model.InsertManyOptions;
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiInsertManyOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiInsertManyOpDispenser extends DataApiOpDispenser {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiInsertManyOpDispenser.class);
|
||||
private final LongFunction<DataApiInsertManyOp> opFunction;
|
||||
|
||||
public DataApiInsertManyOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
this.opFunction = createOpFunction(op);
|
||||
}
|
||||
|
||||
private LongFunction<DataApiInsertManyOp> createOpFunction(ParsedOp op) {
|
||||
return (l) -> {
|
||||
List<Document> documents = new ArrayList<>();
|
||||
op.getAsRequiredFunction("documents", List.class).apply(l).forEach(o -> documents.add(Document.parse(o.toString())));
|
||||
return new DataApiInsertManyOp(
|
||||
spaceFunction.apply(l).getDatabase(),
|
||||
targetFunction.apply(l),
|
||||
documents,
|
||||
getInsertManyOptions(op, l)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private InsertManyOptions getInsertManyOptions(ParsedOp op, long l) {
|
||||
InsertManyOptions options = new InsertManyOptions();
|
||||
Optional<LongFunction<Map>> optionsFunction = op.getAsOptionalFunction("options", Map.class);
|
||||
if (optionsFunction.isPresent()) {
|
||||
Map<String, String> optionFields = optionsFunction.get().apply(l);
|
||||
for(Map.Entry<String,String> entry: optionFields.entrySet()) {
|
||||
switch(entry.getKey()) {
|
||||
case "chunkSize"->
|
||||
options = options.chunkSize(Integer.parseInt(entry.getValue()));
|
||||
case "concurrency" ->
|
||||
options = options.concurrency(Integer.parseInt(entry.getValue()));
|
||||
case "ordered" ->
|
||||
options = options.ordered(Boolean.parseBoolean(entry.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return opFunction.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import com.datastax.astra.client.model.Document;
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiInsertOneOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiInsertOneOpDispenser extends DataApiOpDispenser {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiInsertOneOpDispenser.class);
|
||||
private final LongFunction<DataApiInsertOneOp> opFunction;
|
||||
|
||||
public DataApiInsertOneOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
this.opFunction = createOpFunction(op);
|
||||
}
|
||||
|
||||
private LongFunction<DataApiInsertOneOp> createOpFunction(ParsedOp op) {
|
||||
LongFunction<Map> docMapFunc = op.getAsRequiredFunction("document", Map.class);
|
||||
LongFunction<Document> docFunc = (long m) -> new Document(docMapFunc.apply(m));
|
||||
return (l) -> {
|
||||
return new DataApiInsertOneOp(
|
||||
spaceFunction.apply(l).getDatabase(),
|
||||
targetFunction.apply(l),
|
||||
docFunc.apply(l)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return opFunction.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import com.datastax.astra.client.model.Document;
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiInsertOneOp;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiInsertOneVectorOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiInsertOneVectorOpDispenser extends DataApiOpDispenser {
|
||||
private static final Logger logger = LogManager.getLogger(DataApiInsertOneVectorOpDispenser.class);
|
||||
private final LongFunction<DataApiInsertOneVectorOp> opFunction;
|
||||
|
||||
public DataApiInsertOneVectorOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
this.opFunction = createOpFunction(op);
|
||||
}
|
||||
|
||||
private LongFunction<DataApiInsertOneVectorOp> createOpFunction(ParsedOp op) {
|
||||
LongFunction<Map> docMapFunc = op.getAsRequiredFunction("document", Map.class);
|
||||
LongFunction<Document> docFunc = (long m) -> new Document(docMapFunc.apply(m));
|
||||
LongFunction<float[]> vectorF= op.getAsRequiredFunction("vector", float[].class);
|
||||
return (l) -> {
|
||||
return new DataApiInsertOneVectorOp(
|
||||
spaceFunction.apply(l).getDatabase(),
|
||||
targetFunction.apply(l),
|
||||
docFunc.apply(l),
|
||||
vectorF.apply(l)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return opFunction.apply(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import com.datastax.astra.client.model.*;
|
||||
import io.nosqlbench.adapter.dataapi.DataApiSpace;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapters.api.activityimpl.BaseOpDispenser;
|
||||
import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public abstract class DataApiOpDispenser extends BaseOpDispenser<DataApiBaseOp, DataApiSpace> {
|
||||
protected final LongFunction<String> targetFunction;
|
||||
protected final LongFunction<DataApiSpace> spaceFunction;
|
||||
|
||||
protected DataApiOpDispenser(DriverAdapter<? extends DataApiBaseOp, DataApiSpace> adapter, ParsedOp op,
|
||||
LongFunction<String> targetFunction) {
|
||||
super(adapter, op);
|
||||
this.targetFunction = targetFunction;
|
||||
this.spaceFunction = adapter.getSpaceFunc(op);
|
||||
}
|
||||
|
||||
protected Sort getSortFromOp(ParsedOp op, long l) {
|
||||
Sort sort = null;
|
||||
Optional<LongFunction<Map>> sortFunction = op.getAsOptionalFunction("sort", Map.class);
|
||||
if (sortFunction.isPresent()) {
|
||||
Map<String,Object> sortFields = sortFunction.get().apply(l);
|
||||
String sortOrder = sortFields.get("type").toString();
|
||||
String sortField = sortFields.get("field").toString();
|
||||
switch(sortOrder) {
|
||||
case "asc" -> sort = Sorts.ascending(sortField);
|
||||
case "desc" -> sort = Sorts.descending(sortField);
|
||||
}
|
||||
}
|
||||
return sort;
|
||||
}
|
||||
|
||||
protected Filter getFilterFromOp(ParsedOp op, long l) {
|
||||
// TODO: Clarify 'filter' vs 'filters' or whether to support both uniformly
|
||||
Filter filter = null;
|
||||
Optional<LongFunction<List>> filterFunction = op.getAsOptionalFunction("filters", List.class).or(
|
||||
() -> op.getAsOptionalFunction("filter",List.class)
|
||||
);
|
||||
if (filterFunction.isPresent()) {
|
||||
List<Map<String,Object>> filters = filterFunction.get().apply(l);
|
||||
List<Filter> andFilterList = new ArrayList<>();
|
||||
List<Filter> orFilterList = new ArrayList<>();
|
||||
for (Map<String,Object> filterFields : filters) {
|
||||
switch ((String)filterFields.get("conjunction")) {
|
||||
case "and" -> {
|
||||
switch (filterFields.get("operator").toString()) {
|
||||
case "lt" ->
|
||||
andFilterList.add(Filters.lt(filterFields.get("field").toString(), (long) filterFields.get("value")));
|
||||
case "gt" ->
|
||||
andFilterList.add(Filters.gt(filterFields.get("field").toString(), (long) filterFields.get("value")));
|
||||
case "eq" ->
|
||||
andFilterList.add(Filters.eq(filterFields.get("field").toString(), filterFields.get("value")));
|
||||
default -> logger.error(() -> "Operation " + filterFields.get("operator") + " not supported");
|
||||
}
|
||||
}
|
||||
case "or" -> {
|
||||
switch (filterFields.get("operator").toString()) {
|
||||
case "lt" ->
|
||||
orFilterList.add(Filters.lt(filterFields.get("field").toString(), (long) filterFields.get("value")));
|
||||
case "gt" ->
|
||||
orFilterList.add(Filters.gt(filterFields.get("field").toString(), (long) filterFields.get("value")));
|
||||
case "eq" ->
|
||||
orFilterList.add(Filters.eq(filterFields.get("field").toString(), filterFields.get("value")));
|
||||
default -> logger.error(() -> "Operation " + filterFields.get("operator") + " not supported");
|
||||
}
|
||||
}
|
||||
default -> logger.error(() -> "Conjunction " + filterFields.get("conjunction") + " not supported");
|
||||
}
|
||||
}
|
||||
if (!andFilterList.isEmpty())
|
||||
filter = Filters.and(andFilterList.toArray(new Filter[0]));
|
||||
if (!orFilterList.isEmpty())
|
||||
filter = Filters.or(orFilterList.toArray(new Filter[0]));
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
protected Update getUpdates(ParsedOp op, long l) {
|
||||
Update update = new Update();
|
||||
Optional<LongFunction<Map>> updatesFunction = op.getAsOptionalFunction("updates", Map.class);
|
||||
if (updatesFunction.isPresent()) {
|
||||
Map<String, Object> updates = updatesFunction.get().apply(l);
|
||||
for (Map.Entry<String, Object> entry : updates.entrySet()) {
|
||||
if (entry.getKey().equalsIgnoreCase("update")) {
|
||||
Map<String, Object> updateFields = (Map<String, Object>) entry.getValue();
|
||||
switch (updateFields.get("operation").toString()) {
|
||||
case "set" ->
|
||||
update = Updates.set(updateFields.get("field").toString(), updateFields.get("value"));
|
||||
case "inc" ->
|
||||
update = Updates.inc(updateFields.get("field").toString(), (double) updateFields.get("value"));
|
||||
case "unset" -> update = Updates.unset(updateFields.get("field").toString());
|
||||
case "addToSet" ->
|
||||
update = Updates.addToSet(updateFields.get("field").toString(), updateFields.get("value"));
|
||||
case "min" ->
|
||||
update = Updates.min(updateFields.get("field").toString(), (double) updateFields.get("value"));
|
||||
case "rename" ->
|
||||
update = Updates.rename(updateFields.get("field").toString(), updateFields.get("value").toString());
|
||||
default -> logger.error(() -> "Operation " + updateFields.get("operation") + " not supported");
|
||||
}
|
||||
} else {
|
||||
logger.error(() -> "Filter " + entry.getKey() + " not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
return update;
|
||||
}
|
||||
|
||||
protected float[] getVectorValues(ParsedOp op, long l) {
|
||||
Object rawVectorValues = op.get("vector", l);
|
||||
return getVectorValues(rawVectorValues);
|
||||
}
|
||||
|
||||
protected float[] getVectorValues(Object rawVectorValues) {
|
||||
float[] floatValues;
|
||||
if (rawVectorValues instanceof float[] f) {
|
||||
return f;
|
||||
}
|
||||
if (rawVectorValues instanceof String) {
|
||||
String[] rawValues = (((String) rawVectorValues).split(","));
|
||||
floatValues = new float[rawValues.length];
|
||||
for (int i = 0; i < rawValues.length; i++) {
|
||||
floatValues[i] = Float.parseFloat(rawValues[i]);
|
||||
}
|
||||
} else if (rawVectorValues instanceof List) {
|
||||
return getVectorValuesList(rawVectorValues);
|
||||
} else {
|
||||
throw new RuntimeException("Invalid type specified for values (type: " + rawVectorValues.getClass().getSimpleName() + "), values: " + rawVectorValues.toString());
|
||||
}
|
||||
return floatValues;
|
||||
}
|
||||
|
||||
protected float[] getVectorValuesList(Object rawVectorValues) {
|
||||
float[] vectorValues = null;
|
||||
List<Object> vectorValuesList = (List<Object>) rawVectorValues;
|
||||
vectorValues = new float[vectorValuesList.size()];
|
||||
for (int i = 0; i < vectorValuesList.size(); i++) {
|
||||
vectorValues[i] = Float.parseFloat(vectorValuesList.get(i).toString());
|
||||
}
|
||||
return vectorValues;
|
||||
}
|
||||
|
||||
protected Projection[] getProjectionFromOp(ParsedOp op, long l) {
|
||||
Projection[] projection = null;
|
||||
Optional<LongFunction<Map>> projectionFunction = op.getAsOptionalFunction("projection", Map.class);
|
||||
if (projectionFunction.isPresent()) {
|
||||
Map<String,List<String>> projectionFields = projectionFunction.get().apply(l);
|
||||
for (Map.Entry<String,List<String>> field : projectionFields.entrySet()) {
|
||||
List<String> includeFields = field.getValue();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (String includeField : includeFields) {
|
||||
sb.append(includeField).append(",");
|
||||
}
|
||||
sb.deleteCharAt(sb.length() - 1);
|
||||
if (field.getKey().equalsIgnoreCase("include")) {
|
||||
projection = Projections.include(sb.toString());
|
||||
} else if (field.getKey().equalsIgnoreCase("exclude")) {
|
||||
projection = Projections.exclude(sb.toString());
|
||||
} else {
|
||||
logger.error("Projection " + field + " not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
return projection;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiUpdateManyOpDispenser extends DataApiOpDispenser {
|
||||
public DataApiUpdateManyOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.opdispensers;
|
||||
|
||||
import io.nosqlbench.adapter.dataapi.DataApiDriverAdapter;
|
||||
import io.nosqlbench.adapter.dataapi.ops.DataApiBaseOp;
|
||||
import io.nosqlbench.adapters.api.templating.ParsedOp;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class DataApiUpdateOneOpDispenser extends DataApiOpDispenser {
|
||||
public DataApiUpdateOneOpDispenser(DataApiDriverAdapter adapter, ParsedOp op, LongFunction<String> targetFunction) {
|
||||
super(adapter, op, targetFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataApiBaseOp getOp(long value) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.CycleOp;
|
||||
|
||||
public abstract class DataApiBaseOp implements CycleOp {
|
||||
protected final Database db;
|
||||
|
||||
public DataApiBaseOp(Database db) {
|
||||
this.db = db;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.CollectionOptions;
|
||||
|
||||
public class DataApiCreateCollectionOp extends DataApiBaseOp {
|
||||
private final String collectionName;
|
||||
private final CollectionOptions options;
|
||||
|
||||
public DataApiCreateCollectionOp(Database db, String collectionName, CollectionOptions options) {
|
||||
super(db);
|
||||
this.collectionName = collectionName;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(long value) {
|
||||
return db.createCollection(collectionName, options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Collection;
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Filter;
|
||||
|
||||
public class DataApiDeleteManyOp extends DataApiBaseOp {
|
||||
private final Collection collection;
|
||||
private final Filter filter;
|
||||
|
||||
public DataApiDeleteManyOp(Database db, Collection collection, Filter filter) {
|
||||
super(db);
|
||||
this.collection = collection;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(long value) {
|
||||
return collection.deleteMany(filter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Collection;
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.DeleteOneOptions;
|
||||
import com.datastax.astra.client.model.Filter;
|
||||
|
||||
public class DataApiDeleteOneOp extends DataApiBaseOp {
|
||||
private final Collection collection;
|
||||
private final Filter filter;
|
||||
private final DeleteOneOptions options;
|
||||
|
||||
public DataApiDeleteOneOp(Database db, Collection collection, Filter filter, DeleteOneOptions options) {
|
||||
super(db);
|
||||
this.collection = collection;
|
||||
this.filter = filter;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(long value) {
|
||||
return collection.deleteOne(filter, options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
|
||||
public class DataApiDropCollectionOp extends DataApiBaseOp {
|
||||
private final String collectionName;
|
||||
public DataApiDropCollectionOp(Database db, String collectionName) {
|
||||
super(db);
|
||||
this.collectionName = collectionName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(long value) {
|
||||
Boolean exists = db.collectionExists(collectionName);
|
||||
// TODO: we need to remove these from the ops when we can, because this hides additional ops which
|
||||
// should be surfaced in the test definition. Condition operations should be provided with clear views
|
||||
// at the workload template level
|
||||
if (exists) {
|
||||
db.dropCollection(collectionName);
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Collection;
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Document;
|
||||
import com.datastax.astra.client.model.Filter;
|
||||
import com.datastax.astra.client.model.FindOneAndDeleteOptions;
|
||||
|
||||
public class DataApiFindOneAndDeleteOp extends DataApiBaseOp {
|
||||
private final Collection<Document> collection;
|
||||
private final Filter filter;
|
||||
private final FindOneAndDeleteOptions options;
|
||||
|
||||
public DataApiFindOneAndDeleteOp(Database db, Collection<Document> collection, Filter filter, FindOneAndDeleteOptions options) {
|
||||
super(db);
|
||||
this.collection = collection;
|
||||
this.filter = filter;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(long value) {
|
||||
return collection.findOneAndDelete(filter, options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Collection;
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.*;
|
||||
|
||||
public class DataApiFindOneAndUpdateOp extends DataApiBaseOp {
|
||||
private final Collection<Document> collection;
|
||||
private final Filter filter;
|
||||
private final Update update;
|
||||
|
||||
public DataApiFindOneAndUpdateOp(Database db, Collection<Document> collection, Filter filter, Update update) {
|
||||
super(db);
|
||||
this.collection = collection;
|
||||
this.filter = filter;
|
||||
this.update = update;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(long value) {
|
||||
return collection.findOneAndUpdate(filter, update);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Collection;
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Document;
|
||||
import com.datastax.astra.client.model.Filter;
|
||||
import com.datastax.astra.client.model.FindOneOptions;
|
||||
|
||||
public class DataApiFindOneOp extends DataApiBaseOp {
|
||||
private final Collection<Document> collection;
|
||||
private final Filter filter;
|
||||
private final FindOneOptions options;
|
||||
|
||||
public DataApiFindOneOp(Database db, Collection<Document> collection, Filter filter, FindOneOptions options) {
|
||||
super(db);
|
||||
this.collection = collection;
|
||||
this.filter = filter;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(long value) {
|
||||
return collection.findOne(filter, options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Collection;
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
public class DataApiFindOp extends DataApiBaseOp {
|
||||
private final Collection<Document> collection;
|
||||
private final Filter filter;
|
||||
private final FindOptions options;
|
||||
|
||||
public DataApiFindOp(Database db, Collection<Document> collection, Filter filter, FindOptions options) {
|
||||
super(db);
|
||||
this.collection = collection;
|
||||
this.filter = filter;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Document> apply(long value) {
|
||||
// TODO: make sure we're traversing result data
|
||||
FindIterable<Document> documentStream = collection.find(filter, options);
|
||||
List<Document> documents = StreamSupport.stream(documentStream.spliterator(), false).toList();
|
||||
return documents;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Collection;
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Document;
|
||||
import com.datastax.astra.client.model.Filter;
|
||||
|
||||
public class DataApiFindVectorFilterOp extends DataApiBaseOp {
|
||||
private final Collection<Document> collection;
|
||||
private final float[] vector;
|
||||
private final int limit;
|
||||
private final Filter filter;
|
||||
|
||||
public DataApiFindVectorFilterOp(Database db, Collection<Document> collection, float[] vector, int limit, Filter filter) {
|
||||
super(db);
|
||||
this.collection = collection;
|
||||
this.vector = vector;
|
||||
this.limit = limit;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(long value) {
|
||||
return collection.find(filter, vector, limit);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Collection;
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Document;
|
||||
import com.datastax.astra.client.model.Filter;
|
||||
import com.datastax.astra.client.model.FindOptions;
|
||||
|
||||
public class DataApiFindVectorOp extends DataApiBaseOp {
|
||||
private final Collection<Document> collection;
|
||||
private final float[] vector;
|
||||
private final int limit;
|
||||
|
||||
public DataApiFindVectorOp(Database db, Collection<Document> collection, float[] vector, int limit) {
|
||||
super(db);
|
||||
this.collection = collection;
|
||||
this.vector = vector;
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(long value) {
|
||||
return collection.find(vector, limit);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Document;
|
||||
import com.datastax.astra.client.model.InsertManyOptions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DataApiInsertManyOp extends DataApiBaseOp {
|
||||
private final List<? extends Document> documents;
|
||||
private final String collectionName;
|
||||
private final InsertManyOptions options;
|
||||
|
||||
|
||||
public DataApiInsertManyOp(Database db, String collectionName, List<? extends Document> documents, InsertManyOptions options) {
|
||||
super(db);
|
||||
this.collectionName = collectionName;
|
||||
this.documents = documents;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(long value) {
|
||||
return db.getCollection(collectionName).insertMany(documents, options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Document;
|
||||
|
||||
public class DataApiInsertOneOp extends DataApiBaseOp {
|
||||
private final Document doc;
|
||||
private final String collectionName;
|
||||
|
||||
public DataApiInsertOneOp(Database db, String collectionName, Document doc) {
|
||||
super(db);
|
||||
this.collectionName = collectionName;
|
||||
this.doc = doc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(long value) {
|
||||
return db.getCollection(collectionName).insertOne(doc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
import com.datastax.astra.client.Database;
|
||||
import com.datastax.astra.client.model.Document;
|
||||
|
||||
public class DataApiInsertOneVectorOp extends DataApiBaseOp {
|
||||
private final Document doc;
|
||||
private final String collectionName;
|
||||
private float[] vector;
|
||||
|
||||
public DataApiInsertOneVectorOp(Database db, String collectionName, Document doc, float[] vector) {
|
||||
super(db);
|
||||
this.collectionName = collectionName;
|
||||
this.doc = doc;
|
||||
this.vector = vector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(long value) {
|
||||
return db.getCollection(collectionName).insertOne(doc, vector);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2024 nosqlbench
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.nosqlbench.adapter.dataapi.ops;
|
||||
|
||||
public enum DataApiOpType {
|
||||
create_collection,
|
||||
insert_many,
|
||||
insert_one,
|
||||
insert_one_vector,
|
||||
find,
|
||||
find_one,
|
||||
find_one_and_delete,
|
||||
find_one_and_update,
|
||||
find_vector,
|
||||
find_vector_filter,
|
||||
update_one,
|
||||
update_many,
|
||||
delete_one,
|
||||
delete_many,
|
||||
delete_collection
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
min_version: "5.21.0"
|
||||
|
||||
description: |
|
||||
A basic workload that uses the DataStax Data API Client in Java, emulating what
|
||||
applications would do in the native stack.
|
||||
TEMPLATE(cardinality,1000)
|
||||
TEMPLATE(collection,keyvalue)
|
||||
TEMPLATE(dimensions,1536)
|
||||
TEMPLATE(similarity,COSINE)
|
||||
TEMPLATE(keycount,TEMPLATE(cardinality))
|
||||
TEMPLATE(valuecount,TEMPLATE(cardinality))
|
||||
|
||||
scenarios:
|
||||
dapi_novector:
|
||||
schema: run driver=dataapi tags==block:schema threads==1 cycles==UNDEF
|
||||
rampup: >-
|
||||
run driver=dataapi tags==block:rampup
|
||||
cycles===TEMPLATE(rampup-cycles,TEMPLATE(cardinality))
|
||||
threads=auto errors=count
|
||||
find_key: >-
|
||||
run driver=dataapi tags==block:find_key
|
||||
cycles===TEMPLATE(main-cycles,1000)
|
||||
threads=auto errors=count
|
||||
|
||||
dapi_vector_d1536:
|
||||
schema_vector: run driver=dataapi tags==block:schema_vector threads==1 cycles==UNDEF
|
||||
rampup_vector: >-
|
||||
run driver=dataapi tags==block:rampup_vector
|
||||
cycles===TEMPLATE(rampup-cycles,TEMPLATE(cardinality))
|
||||
threads=auto errors=count
|
||||
find_key_vector: >-
|
||||
run driver=dataapi tags==block:find_key_vector
|
||||
cycles===TEMPLATE(main-cycles,TEMPLATE(cardinality))
|
||||
threads=auto errors=count
|
||||
|
||||
|
||||
|
||||
# kv_dapi:
|
||||
# kv_dapi_schema: run driver=http tags==block:schema threads==1 cycles==UNDEF
|
||||
# kv_dapi_rampup: run driver=http tags==block:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
|
||||
# kv_dapi_main: run driver=http tags==block:"main.*" cycles===TEMPLATE(main-cycles,10000000) threads=auto
|
||||
|
||||
# basic_check:
|
||||
# schema: run driver=http tags==block:schema threads==1 cycles==UNDEF
|
||||
# rampup: run driver=http tags==block:rampup cycles===TEMPLATE(rampup-cycles,10) threads=auto
|
||||
# main: run driver=http tags==block:"main.*" cycles===TEMPLATE(main-cycles,10) threads=auto
|
||||
|
||||
bindings:
|
||||
# To enable an optional weighted set of hosts in place of a load balancer
|
||||
# Examples
|
||||
# single host: jsonapi_host=host1
|
||||
# multiple hosts: jsonapi_host=host1,host2,host3
|
||||
# multiple weighted hosts: jsonapi_host=host1:3,host2:7
|
||||
weighted_hosts: WeightedStrings('TEMPLATE(jsonapi_host,TEMPLATE(stargate_host,localhost))')
|
||||
|
||||
seq_key: Mod(TEMPLATE(keycount)); ToString() -> String
|
||||
# seq_key: Mod(TEMPLATE(keycount,50000000000L));
|
||||
seq_value: Hash(); Mod(TEMPLATE(valuecount)); ToString() -> String
|
||||
# rw_key: TEMPLATE(keydist,Uniform(0,50000000000L));
|
||||
rw_key: TEMPLATE(keydist,Uniform(0,TEMPLATE(keycount))); ToString() -> String
|
||||
rw_key_num: TEMPLATE(keydist,Uniform(0,TEMPLATE(keycount)));
|
||||
rw_value: Hash(); TEMPLATE(valdist,Uniform(0,TEMPLATE(valuecount))); ToString() -> String
|
||||
vector_value: HashedFloatVectors(TEMPLATE(dimensions,1536));
|
||||
|
||||
request_id: ToHashedUUID(); ToString();
|
||||
|
||||
params:
|
||||
cl: TEMPLATE(cl,LOCAL_QUORUM)
|
||||
|
||||
blocks:
|
||||
reset_schema:
|
||||
ops:
|
||||
drop_index:
|
||||
raw: |-
|
||||
DROP INDEX IF EXISTS TEMPLATE(keyspace, baselines).TEMPLATE(table,keyvalue)_value_idx;
|
||||
drop-table:
|
||||
raw: |-
|
||||
DROP TABLE IF EXISTS TEMPLATE(keyspace, baselines).TEMPLATE(table,keyvalue);
|
||||
|
||||
schema:
|
||||
ops:
|
||||
delete_collection_op:
|
||||
delete_collection: "TEMPLATE(collection)"
|
||||
create_collection_op:
|
||||
create_collection: "TEMPLATE(collection)"
|
||||
|
||||
# separate these cases later, when you can recreate the same collection name with/without vector support
|
||||
schema_vector:
|
||||
ops:
|
||||
delete_collection_op_v:
|
||||
delete_collection: "TEMPLATE(collection)_v"
|
||||
create_collection_op_v:
|
||||
create_collection: "TEMPLATE(collection)_v"
|
||||
dimensions: TEMPLATE(dimensions)
|
||||
similarity: TEMPLATE(similarity)
|
||||
|
||||
rampup:
|
||||
ops:
|
||||
insert_one_op:
|
||||
insert_one: "TEMPLATE(collection)"
|
||||
document:
|
||||
_id: "{seq_key}"
|
||||
value: "{seq_value}"
|
||||
|
||||
rampup_vector:
|
||||
ops:
|
||||
insert_one_op_v:
|
||||
insert_one_vector: "TEMPLATE(collection)_v"
|
||||
document:
|
||||
_id: "{seq_key}"
|
||||
value: "{seq_value}"
|
||||
vector: "{vector_value}"
|
||||
|
||||
# rampup-uuid:
|
||||
# ops:
|
||||
# insert_one_op:
|
||||
# insert-one: "TEMPLATE(collection)"
|
||||
# document:
|
||||
# value: "{seq_value}"
|
||||
find_key:
|
||||
params:
|
||||
ratio: 5
|
||||
ops:
|
||||
find_op:
|
||||
find: "TEMPLATE(collection)"
|
||||
filters:
|
||||
- conjunction: "and"
|
||||
operator: "lt"
|
||||
field: "_id"
|
||||
value: "{rw_key_num}"
|
||||
vector: "{vector_value}"
|
||||
|
||||
find_key_vector:
|
||||
params:
|
||||
ratio: 5
|
||||
ops:
|
||||
find_op_v:
|
||||
find_vector_filter: "TEMPLATE(collection)"
|
||||
filters:
|
||||
- conjunction: "and"
|
||||
operator: "lt"
|
||||
field: "_id"
|
||||
value: "{rw_key_num}"
|
||||
vector: "{vector_value}"
|
||||
|
||||
|
||||
#
|
||||
# rampup_with_vector_uuid:
|
||||
# ops:
|
||||
# insert_one_op:
|
||||
# insert_one: "TEMPLATE(collection)"
|
||||
# document:
|
||||
# value: "{seq_value}"
|
||||
# vector: "{vector_value}"
|
||||
#
|
||||
# main_read_with_vector:
|
||||
# ops:
|
||||
# find_op:
|
||||
# find: "TEMPLATE(collection)"
|
||||
# filter:
|
||||
# _id: "{rw_key}"
|
||||
#
|
||||
# main_ann_with_vector_limit_20:
|
||||
# params:
|
||||
# ratio: 5
|
||||
# ops:
|
||||
# find_op:
|
||||
# find: "TEMPLATE(collection)"
|
||||
# sort:
|
||||
# vector: "{vector_value}"
|
||||
# options:
|
||||
# limit: 20
|
||||
# schema_with_text_sai:
|
||||
# ops:
|
||||
# delete_collection_op:
|
||||
# delete_collection: "TEMPLATE(collection)"
|
||||
# create_collection_op:
|
||||
# create_collection: "TEMPLATE(collection)"
|
||||
# rampup_with_text_sai:
|
||||
# ops:
|
||||
# insert_one_op:
|
||||
# insert_one: "TEMPLATE(collection)"
|
||||
# document:
|
||||
# _id: "{seq_key}"
|
||||
# value: "{seq_value}"
|
||||
# main_read_with_text_sai:
|
||||
# params:
|
||||
# ratio: 5
|
||||
# ops:
|
||||
# find_op:
|
||||
# find: "TEMPLATE(collection)"
|
||||
# filter:
|
||||
# value: "{rw_value}"
|
||||
@@ -0,0 +1,11 @@
|
||||
scenarios:
|
||||
default:
|
||||
create_collection: run driver=dataapi tags==blocks:create_collection cycles=1
|
||||
|
||||
blocks:
|
||||
create_collection:
|
||||
ops:
|
||||
op1:
|
||||
create_collection: "collectionName"
|
||||
dimensions: 10
|
||||
similarity: "COSINE"
|
||||
@@ -0,0 +1,18 @@
|
||||
scenarios:
|
||||
default:
|
||||
delete_many: run driver=dataapi tags==blocks:delete_many cycles=1
|
||||
|
||||
blocks:
|
||||
delete_many:
|
||||
ops:
|
||||
op1:
|
||||
delete_many: "collectionName"
|
||||
filters:
|
||||
- conjunction: "and"
|
||||
operator: "lt"
|
||||
field: "field1"
|
||||
value: 10
|
||||
- conjunction: "or"
|
||||
operator: "eq"
|
||||
field: "field2"
|
||||
value: "value2"
|
||||
@@ -0,0 +1,13 @@
|
||||
scenarios:
|
||||
default:
|
||||
delete_one: run driver=dataapi tags==blocks:delete_one cycles=1
|
||||
|
||||
blocks:
|
||||
delete_one:
|
||||
ops:
|
||||
op1:
|
||||
delete_one: "collectionName"
|
||||
sort:
|
||||
type: "asc"
|
||||
field: "field1"
|
||||
vector: "1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0"
|
||||
@@ -0,0 +1,9 @@
|
||||
scenarios:
|
||||
default:
|
||||
drop_collection: run driver=dataapi tags==blocks:drop_collection cycles=1
|
||||
|
||||
blocks:
|
||||
drop_collection:
|
||||
ops:
|
||||
op1:
|
||||
drop_collection: "collectionName"
|
||||
@@ -0,0 +1,26 @@
|
||||
scenarios:
|
||||
default:
|
||||
find: run driver=dataapi tags==blocks:find cycles=10
|
||||
|
||||
blocks:
|
||||
find:
|
||||
ops:
|
||||
op1:
|
||||
find: "collectionName"
|
||||
filters:
|
||||
- conjunction: "and"
|
||||
operator: "lt"
|
||||
field: "field1"
|
||||
value: 10
|
||||
- conjunction: "or"
|
||||
operator: "eq"
|
||||
field: "field2"
|
||||
value: "value2"
|
||||
sort:
|
||||
type: "asc"
|
||||
field: "field1"
|
||||
vector: "1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0"
|
||||
projection:
|
||||
include:
|
||||
- "field1"
|
||||
- "field2"
|
||||
@@ -0,0 +1,26 @@
|
||||
scenarios:
|
||||
default:
|
||||
find_one: run driver=dataapi tags==blocks:find_one cycles=10
|
||||
|
||||
blocks:
|
||||
find_one:
|
||||
ops:
|
||||
op1:
|
||||
find_one: "collectionName"
|
||||
filters:
|
||||
- conjunction: "and"
|
||||
operator: "lt"
|
||||
field: "field1"
|
||||
value: 10
|
||||
- conjunction: "or"
|
||||
operator: "eq"
|
||||
field: "field2"
|
||||
value: "value2"
|
||||
sort:
|
||||
type: "asc"
|
||||
field: "field1"
|
||||
vector: "1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0"
|
||||
projection:
|
||||
include:
|
||||
- "field1"
|
||||
- "field2"
|
||||
@@ -0,0 +1,25 @@
|
||||
scenarios:
|
||||
default:
|
||||
find_one_and_delete: run driver=dataapi tags==blocks:find_one_and_delete cycles=1
|
||||
|
||||
blocks:
|
||||
find_one_and_delete:
|
||||
ops:
|
||||
op1:
|
||||
find_one_and_delete: "collectionName"
|
||||
filters:
|
||||
- conjunction: "and"
|
||||
operator: "lt"
|
||||
field: "field1"
|
||||
value: 10
|
||||
- conjunction: "or"
|
||||
operator: "eq"
|
||||
field: "field2"
|
||||
value: "value2"
|
||||
sort:
|
||||
type: "asc"
|
||||
field: "field1"
|
||||
projection:
|
||||
include:
|
||||
- "field1"
|
||||
- "field2"
|
||||
@@ -0,0 +1,17 @@
|
||||
scenarios:
|
||||
default:
|
||||
insert_many: run driver=dataapi tags==blocks:insert_many cycles=1
|
||||
|
||||
blocks:
|
||||
insert_many:
|
||||
ops:
|
||||
op1:
|
||||
insert_many: "collectionName"
|
||||
options:
|
||||
chunkSize: "1000"
|
||||
concurrency: "10"
|
||||
ordered: "false"
|
||||
documents:
|
||||
- "{valid json here}"
|
||||
- "{valid json here}"
|
||||
- "{valid json here}"
|
||||
@@ -0,0 +1,10 @@
|
||||
scenarios:
|
||||
default:
|
||||
insert_one: run driver=dataapi tags==blocks:insert_one cycles=1
|
||||
|
||||
blocks:
|
||||
insert_one:
|
||||
ops:
|
||||
op1:
|
||||
insert_one: "collectionName"
|
||||
document: "{valid json here}"
|
||||
@@ -0,0 +1,11 @@
|
||||
scenarios:
|
||||
default:
|
||||
insert_one: run driver=dataapi tags==blocks:insert_one cycles=1
|
||||
|
||||
blocks:
|
||||
insert_one:
|
||||
ops:
|
||||
op1:
|
||||
insert_one: "collectionName"
|
||||
document: "{valid json here}"
|
||||
vector: "1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0"
|
||||
@@ -141,6 +141,20 @@
|
||||
</dependencies>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>adapter-dataapi-include</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.nosqlbench</groupId>
|
||||
<artifactId>adapter-dataapi</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>adapter-dynamodb-include</id>
|
||||
<activation>
|
||||
@@ -186,7 +200,7 @@
|
||||
<profile>
|
||||
<id>adapter-s4j-include</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@@ -252,6 +266,7 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--
|
||||
~ Copyright (c) 2022-2024 nosqlbench
|
||||
~ Copyright (c) 2022-2023 nosqlbench
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
@@ -147,7 +147,7 @@
|
||||
<profile>
|
||||
<id>adapter-s4j-module</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>adapter-s4j</module>
|
||||
@@ -174,6 +174,16 @@
|
||||
</modules>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>adapter-dataapi-module</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>adapter-dataapi</module>
|
||||
</modules>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>adapter-qdrant-module</id>
|
||||
<activation>
|
||||
|
||||
@@ -178,7 +178,7 @@ public class NBConfiguration {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new NBConfigError("Parameter was not found for " + Arrays.toString(names) + ".");
|
||||
throw new NBConfigError("Parameter definition was not found for " + Arrays.toString(names) + ".");
|
||||
}
|
||||
}
|
||||
if (o == null) {
|
||||
|
||||
@@ -136,6 +136,9 @@ public class Param<T> {
|
||||
* @return
|
||||
*/
|
||||
public static <V> Param<V> defaultTo(String name, V defaultValue) {
|
||||
if (defaultValue instanceof Class clazz) {
|
||||
throw new RuntimeException("This is not a supported type.");
|
||||
}
|
||||
return new Param<V>(List.of(name), (Class<V>) defaultValue.getClass(), null, true, defaultValue, null);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,22 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ParsedTemplateMapTest {
|
||||
|
||||
// @Test
|
||||
// public void testBindpointTypes() {
|
||||
// ParsedTemplateMap ptm = new ParsedTemplateMap(
|
||||
// "name1",
|
||||
// Map.of(
|
||||
// "field1","{binding1}",
|
||||
// "field2", " {binding2}"
|
||||
// ),
|
||||
// Map.of(
|
||||
// "binding1","TestingStringFunc('b1')",
|
||||
// "binding2","TestingStringFunc('b2')"
|
||||
// ),
|
||||
// List.of(Map.of()));
|
||||
//
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void testParsedTemplateMap() {
|
||||
ParsedTemplateMap ptm = new ParsedTemplateMap("name1", Map.of("string1", "string2"), Map.of(), List.of());
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!--
|
||||
/<!--
|
||||
~ Copyright (c) 2022-2023 nosqlbench
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
Reference in New Issue
Block a user