Skip to content
23 changes: 23 additions & 0 deletions simple/run-vector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
function main () {
global.returnValue = 0;
require("./simple/test").test({
outputCsv: false,
small: true,
runs: 3,
documents: false,
ioless: false,
edges: false,
search: false,
phrase: false,
noMaterializationSearch: false,
crud: false,
crudSearch: false,
subqueryTests: false,
mditests: false,
vectorTests: true
});
return global.returnValue;
}
if (typeof arango !== "undefined") {
process.exit(main());
}
127 changes: 127 additions & 0 deletions simple/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ function sum (values) {
}
}

function randomNumberGeneratorFloat(seed) {
const rng = (function* (seed) {
while (true) {
const nextVal = Math.cos(seed++);
yield nextVal;
}
})(seed);

return function () {
return rng.next().value;
};
}

function calc (values, options) {
values.sort((a, b) => a - b);

Expand Down Expand Up @@ -154,6 +167,10 @@ exports.test = function (global) {
if (options.hasOwnProperty("iterations")) {
params.iterations = options.iterations;
}
if (options.hasOwnProperty("extras")) {
params.extras = options.extras;
}

return params;
};

Expand Down Expand Up @@ -3320,6 +3337,59 @@ exports.test = function (global) {
},
];

function vectorTest (params) {
let bindParam = { "@col": params.collection, "qp": params.extras.queryPoint };
if ("bindParamModifier" in params) {
params.bindParamModifier(params, bindParam);
}
db._query(
params.queryString,
bindParam,
);
}

function vectorTestNoParams (params) {
let bindParam = { "@col": params.collection };
if ("bindParamModifier" in params) {
params.bindParamModifier(params, bindParam);
}
db._query(
params.queryString,
bindParam,
);
}

let VectorTests = [
{
name: "aql-vector-top-k",
params: {
func: vectorTest,
queryString: `
FOR d IN @@col
SORT APPROX_NEAR_L2(d.vector, @qp)
LIMIT 5
RETURN d`
}
},
{
name: "aql-vector-subquery-10-points",
params: {
func: vectorTestNoParams,
queryString: `
FOR docOuter IN @@col
LIMIT 10
LET neibhours = (
FOR docInner IN @@col
LET dist = APPROX_NEAR_L2(docInner.vector, docOuter.vector)
SORT dist
LIMIT 10
RETURN {dist, doc: docInner._key}
)
RETURN {doc: docOuter._key, neibhours: neibhours}`
}
},
];

const runSatelliteGraphTests = (global.satelliteGraphTests && isEnterprise && isCluster);

if (global.documents || global.edges || global.noMaterializationSearch || global.subqueryTests || runSatelliteGraphTests) {
Expand Down Expand Up @@ -3428,6 +3498,63 @@ exports.test = function (global) {
runTestSuite("MDI", MdiTests, options);
}

// vector tests
if (global.vectorTests) {
const dimension = 500;
let gen = randomNumberGeneratorFloat(3243758343);
let randomPoint = Array.from({ length: dimension }, () => gen());

options = {
runs: global.runs,
digits: global.digits,
setup: function (params) {
db._drop(params.collection);
let col = db._create(params.collection);

let docs = [];
for (let i = 0; i < params.collectionSize; ++i) {
const vector = Array.from({ length: dimension }, () => gen());
if (i === 2000) {
randomPoint = vector;
}
docs.push({ vector });
}
col.insert(docs);

col.ensureIndex({
name: "vector_l2",
type: "vector",
fields: ["vector"],
inBackground: false,
params: { metric: "l2", dimensions: dimension, nLists: params.extras.nLists },
});

},
teardown: function () {},
collections: [],
removeFromResult: 1
};

let extras = { queryPoint: randomPoint };

if (global.tiny) {
options.collections.push({ name: "Vectorvalues1000", label: "1k", size: 1000 });
extras["nLists"]= 10;
} else if (global.small) {
options.collections.push({ name: "Vectorvalues10000", label: "10k", size: 10000 });
extras["nLists"]= 10;
} else if (global.medium) {
options.collections.push({ name: "Vectorvalues100000", label: "100k", size: 100000 });
extras["nLists"]= 100;
} else if (global.big) {
options.collections.push({ name: "Vectorvalues1000000", label: "1000k", size: 1000000 });
extras["nLists"]= 100;
}
options.extras = extras;

runTestSuite("Vector", VectorTests, options);
}

if (global.ioless) {
options = {
runs: global.runs,
Expand Down