mirror of https://gitee.com/bigwinds/arangodb
522 lines
18 KiB
JavaScript
522 lines
18 KiB
JavaScript
/*jshint globalstrict:false, strict:false, maxlen: 500 */
|
|
/*global assertUndefined, assertEqual, assertTrue, assertFalse*/
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief tests for iresearch usage
|
|
///
|
|
/// @file
|
|
///
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
|
///
|
|
/// 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.
|
|
///
|
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
|
///
|
|
/// @author Jan Steemann
|
|
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var jsunity = require("jsunity");
|
|
var db = require("@arangodb").db;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function iResearchAqlTestSuite () {
|
|
var c;
|
|
var v;
|
|
|
|
return {
|
|
setUp : function () {
|
|
db._drop("UnitTestsCollection");
|
|
c = db._create("UnitTestsCollection");
|
|
|
|
db._drop("AnotherUnitTestsCollection");
|
|
var ac = db._create("AnotherUnitTestsCollection");
|
|
|
|
db._dropView("UnitTestsView");
|
|
v = db._createView("UnitTestsView", "arangosearch", {});
|
|
var meta = {
|
|
links: {
|
|
"UnitTestsCollection": {
|
|
includeAllFields: true,
|
|
storeValues: "id",
|
|
fields: {
|
|
text: { analyzers: [ "text_en" ] }
|
|
}
|
|
}
|
|
}
|
|
};
|
|
v.properties(meta);
|
|
|
|
ac.save({ a: "foo", id : 0 });
|
|
ac.save({ a: "ba", id : 1 });
|
|
|
|
for (let i = 0; i < 5; i++) {
|
|
c.save({ a: "foo", b: "bar", c: i });
|
|
c.save({ a: "foo", b: "baz", c: i });
|
|
c.save({ a: "bar", b: "foo", c: i });
|
|
c.save({ a: "baz", b: "foo", c: i });
|
|
}
|
|
|
|
c.save({ name: "full", text: "the quick brown fox jumps over the lazy dog" });
|
|
c.save({ name: "half", text: "quick fox over lazy" });
|
|
c.save({ name: "other half", text: "the brown jumps the dog" });
|
|
c.save({ name: "quarter", text: "quick over" });
|
|
|
|
c.save({ name: "numeric", anotherNumericField: 0 });
|
|
c.save({ name: "null", anotherNullField: null });
|
|
c.save({ name: "bool", anotherBoolField: true });
|
|
c.save({ _key: "foo", xyz: 1 });
|
|
},
|
|
|
|
tearDown : function () {
|
|
var meta = { links : { "UnitTestsCollection": null } };
|
|
v.properties(meta);
|
|
v.drop();
|
|
db._drop("UnitTestsCollection");
|
|
db._drop("AnotherUnitTestsCollection");
|
|
},
|
|
|
|
testTransactionRegistration : function () {
|
|
// read lock
|
|
var result = db._executeTransaction({
|
|
collections: {
|
|
allowImplicit: false,
|
|
read: [ v.name() ]
|
|
},
|
|
action: function () {
|
|
var db = require("@arangodb").db;
|
|
var c = db._collection("UnitTestsCollection");
|
|
return {length: c.toArray().length, value: c.document('foo').xyz};
|
|
}
|
|
});
|
|
assertEqual(1, result.value);
|
|
assertEqual(28, result.length);
|
|
|
|
// write lock
|
|
result = db._executeTransaction({
|
|
collections: {
|
|
allowImplicit: false,
|
|
write: [ v.name() ]
|
|
},
|
|
action: function () {
|
|
var db = require("@arangodb").db;
|
|
var c = db._collection("UnitTestsCollection");
|
|
c.save({ _key: "bar", xyz: 2 });
|
|
return c.toArray().length;
|
|
}
|
|
});
|
|
assertEqual(29, result);
|
|
|
|
// exclusive lock
|
|
result = db._executeTransaction({
|
|
collections: {
|
|
allowImplicit: false,
|
|
exclusive: [ v.name() ]
|
|
},
|
|
action: function () {
|
|
var db = require("@arangodb").db;
|
|
var c = db._collection("UnitTestsCollection");
|
|
c.save({ _key: "baz", xyz: 3 });
|
|
return c.toArray().length;
|
|
}
|
|
});
|
|
assertEqual(30, result);
|
|
},
|
|
|
|
testAttributeEqualityFilter : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER doc.a == 'foo' RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 10);
|
|
result.forEach(function(res) {
|
|
assertEqual(res.a, "foo");
|
|
});
|
|
},
|
|
|
|
testMultipleAttributeEqualityFilter : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER doc.a == 'foo' && doc.b == 'bar' RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 5);
|
|
result.forEach(function(res) {
|
|
assertEqual(res.a, "foo");
|
|
assertEqual(res.b, "bar");
|
|
});
|
|
},
|
|
|
|
testMultipleAttributeEqualityFilterSortAttribute : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER doc.a == 'foo' && doc.b == 'bar' SORT doc.c RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 5);
|
|
var last = -1;
|
|
result.forEach(function(res) {
|
|
assertEqual(res.a, "foo");
|
|
assertEqual(res.b, "bar");
|
|
assertEqual(res.c, last + 1);
|
|
last = res.c;
|
|
});
|
|
},
|
|
|
|
testMultipleAttributeEqualityFilterSortAttributeDesc : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER doc.a == 'foo' AND doc.b == 'bar' SORT doc.c DESC RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 5);
|
|
var last = 5;
|
|
result.forEach(function(res) {
|
|
assertEqual(res.a, "foo");
|
|
assertEqual(res.b, "bar");
|
|
assertEqual(res.c, last - 1);
|
|
last = res.c;
|
|
});
|
|
},
|
|
|
|
testAttributeLessFilter : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER doc.c < 2 RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 8);
|
|
result.forEach(function(res) {
|
|
assertTrue(res.c < 2);
|
|
});
|
|
},
|
|
|
|
testAttributeLeqFilter : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER doc.c <= 2 RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 12);
|
|
result.forEach(function(res) {
|
|
assertTrue(res.c <= 2);
|
|
});
|
|
},
|
|
|
|
testAttributeGeqFilter : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER doc.c >= 2 RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 12);
|
|
result.forEach(function(res) {
|
|
assertTrue(res.c >= 2);
|
|
});
|
|
},
|
|
|
|
testAttributeGreaterFilter : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER doc.c > 2 RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 8);
|
|
result.forEach(function(res) {
|
|
assertTrue(res.c > 2);
|
|
});
|
|
},
|
|
|
|
testAttributeOpenIntervalFilter : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER doc.c > 1 AND doc.c < 3 RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 4);
|
|
result.forEach(function(res) {
|
|
assertTrue(res.c > 1 && res.c < 3);
|
|
});
|
|
},
|
|
|
|
testAttributeClosedIntervalFilter : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER doc.c >= 1 AND doc.c <= 3 RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 12);
|
|
result.forEach(function(res) {
|
|
assertTrue(res.c >= 1 && res.c <= 3);
|
|
});
|
|
},
|
|
|
|
testAttributeIntervalExclusionFilter : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER doc.c < 1 OR doc.c > 3 RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 8);
|
|
result.forEach(function(res) {
|
|
assertTrue(res.c < 1 || res.c > 3);
|
|
});
|
|
},
|
|
|
|
testAttributeNeqFilter : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER doc.a != 'foo' RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 18); // include documents without attribute 'a'
|
|
result.forEach(function(res) {
|
|
assertFalse(res.a === 'foo');
|
|
});
|
|
},
|
|
|
|
testStartsWithFilter : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER STARTS_WITH(doc.a, 'fo') RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 10);
|
|
result.forEach(function(res) {
|
|
assertEqual(res.a, 'foo');
|
|
});
|
|
},
|
|
|
|
testStartsWithFilter2 : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER STARTS_WITH(doc.b, 'ba') RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 10);
|
|
result.forEach(function(res) {
|
|
assertTrue(res.b === 'bar' || res.b === 'baz');
|
|
});
|
|
},
|
|
|
|
testStartsWithFilterSort : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER STARTS_WITH(doc.b, 'ba') && doc.c == 0 SORT doc.b RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 2);
|
|
assertEqual(result[0].b, 'bar');
|
|
assertEqual(result[1].b, 'baz');
|
|
assertEqual(result[0].c, 0);
|
|
assertEqual(result[1].c, 0);
|
|
},
|
|
|
|
testInTokensFilterSortTFIDF : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER ANALYZER(doc.text IN TOKENS('the quick brown', 'text_en'), 'text_en') SORT TFIDF(doc) LIMIT 4 RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 4);
|
|
assertEqual(result[0].name, 'half');
|
|
assertEqual(result[1].name, 'quarter');
|
|
assertEqual(result[2].name, 'other half');
|
|
assertEqual(result[3].name, 'full');
|
|
},
|
|
|
|
testPhraseFilter : function () {
|
|
var result0 = db._query("FOR doc IN VIEW UnitTestsView FILTER PHRASE(doc.text, 'quick brown fox jumps', 'text_en') RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result0.length, 1);
|
|
assertEqual(result0[0].name, 'full');
|
|
|
|
var result1 = db._query("FOR doc IN VIEW UnitTestsView FILTER PHRASE(doc.text, [ 'quick brown fox jumps' ], 'text_en') RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result1.length, 1);
|
|
assertEqual(result1[0].name, 'full');
|
|
|
|
var result2 = db._query("FOR doc IN VIEW UnitTestsView FILTER ANALYZER(PHRASE(doc.text, 'quick brown fox jumps'), 'text_en') RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result2.length, 1);
|
|
assertEqual(result2[0].name, 'full');
|
|
|
|
var result3 = db._query("FOR doc IN VIEW UnitTestsView FILTER ANALYZER(PHRASE(doc.text, [ 'quick brown fox jumps' ]), 'text_en') RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result3.length, 1);
|
|
assertEqual(result3[0].name, 'full');
|
|
},
|
|
|
|
testExistsFilter : function () {
|
|
var expected = new Set();
|
|
expected.add("full");
|
|
expected.add("half");
|
|
expected.add("other half");
|
|
expected.add("quarter");
|
|
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER EXISTS(doc.text) RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, expected.size);
|
|
result.forEach(function(res) {
|
|
assertTrue(expected.delete(res.name));
|
|
});
|
|
assertEqual(expected.size, 0);
|
|
},
|
|
|
|
testExistsFilterByAnalyzer : function () {
|
|
var expected = new Set();
|
|
expected.add("full");
|
|
expected.add("half");
|
|
expected.add("other half");
|
|
expected.add("quarter");
|
|
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER EXISTS(doc.text, 'analyzer', 'text_en') RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, expected.size);
|
|
result.forEach(function(res) {
|
|
assertTrue(expected.delete(res.name));
|
|
});
|
|
assertEqual(expected.size, 0);
|
|
},
|
|
|
|
testExistsFilterByContextAnalyzer: function () {
|
|
var expected = new Set();
|
|
expected.add("full");
|
|
expected.add("half");
|
|
expected.add("other half");
|
|
expected.add("quarter");
|
|
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER ANALYZER(EXISTS(doc.text, 'analyzer'), 'text_en') RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, expected.size);
|
|
result.forEach(function(res) {
|
|
assertTrue(expected.delete(res.name));
|
|
});
|
|
assertEqual(expected.size, 0);
|
|
},
|
|
|
|
testExistsFilterByString: function () {
|
|
var expected = new Set();
|
|
expected.add("full");
|
|
expected.add("half");
|
|
expected.add("other half");
|
|
expected.add("quarter");
|
|
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER EXISTS(doc.text, 'string') RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, expected.size);
|
|
result.forEach(function(res) {
|
|
assertTrue(expected.delete(res.name));
|
|
});
|
|
assertEqual(expected.size, 0);
|
|
},
|
|
|
|
testExistsFilterByType : function () {
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER EXISTS(doc.text, 'type') RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, 0);
|
|
},
|
|
|
|
testExistsFilterByTypeNull : function () {
|
|
var expected = new Set();
|
|
expected.add("null");
|
|
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER EXISTS(doc.anotherNullField, 'null') RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, expected.size);
|
|
result.forEach(function(res) {
|
|
assertTrue(expected.delete(res.name));
|
|
});
|
|
assertEqual(expected.size, 0);
|
|
},
|
|
|
|
testExistsFilterByTypeBool : function () {
|
|
var expected = new Set();
|
|
expected.add("bool");
|
|
|
|
var result = db._query("FOR doc IN VIEW UnitTestsView FILTER EXISTS(doc['anotherBoolField'], 'bool') RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, expected.size);
|
|
result.forEach(function(res) {
|
|
assertTrue(expected.delete(res.name));
|
|
});
|
|
assertEqual(expected.size, 0);
|
|
},
|
|
|
|
testExistsFilterByTypeNumeric : function () {
|
|
var expected = new Set();
|
|
expected.add("numeric");
|
|
|
|
var result = db._query("LET suffix='NumericField' LET fieldName = CONCAT('another', suffix) FOR doc IN VIEW UnitTestsView FILTER EXISTS(doc[fieldName], 'numeric') RETURN doc", null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, expected.size);
|
|
result.forEach(function(res) {
|
|
assertTrue(expected.delete(res.name));
|
|
});
|
|
assertEqual(expected.size, 0);
|
|
},
|
|
|
|
testViewInInnerLoop : function() {
|
|
var expected = new Set(); // FIXME is there a better way to compare objects in js?
|
|
expected.add(JSON.stringify({ a: "foo", b: "bar", c: 0 }));
|
|
expected.add(JSON.stringify({ a: "foo", b: "baz", c: 0 }));
|
|
expected.add(JSON.stringify({ a: "bar", b: "foo", c: 1 }));
|
|
expected.add(JSON.stringify({ a: "baz", b: "foo", c: 1 }));
|
|
|
|
var result = db._query(
|
|
"FOR adoc IN AnotherUnitTestsCollection" +
|
|
" FOR doc IN VIEW UnitTestsView FILTER adoc.id == doc.c && STARTS_WITH(doc['a'], adoc.a) " +
|
|
"RETURN doc"
|
|
, null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, expected.size);
|
|
result.forEach(function(res) {
|
|
assertTrue(expected.delete(JSON.stringify({ a: res.a, b: res.b, c: res.c })));
|
|
});
|
|
assertEqual(expected.size, 0);
|
|
},
|
|
|
|
testViewInInnerLoopMultipleFilters : function() {
|
|
var expected = new Set(); // FIXME is there a better way to compare objects in js?
|
|
expected.add(JSON.stringify({ a: "foo", b: "bar", c: 0 }));
|
|
expected.add(JSON.stringify({ a: "foo", b: "baz", c: 0 }));
|
|
|
|
var result = db._query(
|
|
"FOR adoc IN AnotherUnitTestsCollection FILTER adoc.id < 1" +
|
|
" FOR doc IN VIEW UnitTestsView FILTER adoc.id == doc.c && STARTS_WITH(doc['a'], adoc.a) " +
|
|
"RETURN doc"
|
|
, null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, expected.size);
|
|
result.forEach(function(res) {
|
|
assertTrue(expected.delete(JSON.stringify({ a: res.a, b: res.b, c: res.c })));
|
|
});
|
|
assertEqual(expected.size, 0);
|
|
},
|
|
|
|
testViewInInnerLoopSortByAttribute : function() {
|
|
var expected = [];
|
|
expected.push({ a: "bar", b: "foo", c: 1 });
|
|
expected.push({ a: "baz", b: "foo", c: 1 });
|
|
expected.push({ a: "foo", b: "bar", c: 0 });
|
|
expected.push({ a: "foo", b: "baz", c: 0 });
|
|
|
|
var result = db._query(
|
|
"FOR adoc IN AnotherUnitTestsCollection" +
|
|
" FOR doc IN VIEW UnitTestsView FILTER adoc.id == doc.c && STARTS_WITH(doc['a'], adoc.a) " +
|
|
"SORT doc.c DESC, doc.a, doc.b " +
|
|
"RETURN doc"
|
|
, null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, expected.length);
|
|
var i = 0;
|
|
result.forEach(function(res) {
|
|
var doc = expected[i++];
|
|
assertEqual(doc.a, res.a);
|
|
assertEqual(doc.b, res.b);
|
|
assertEqual(doc.c, res.c);
|
|
});
|
|
},
|
|
|
|
testViewInInnerLoopSortByTFIDF_BM25_Attribute : function() {
|
|
var expected = [];
|
|
expected.push({ a: "baz", b: "foo", c: 1 });
|
|
expected.push({ a: "bar", b: "foo", c: 1 });
|
|
expected.push({ a: "foo", b: "bar", c: 0 });
|
|
expected.push({ a: "foo", b: "baz", c: 0 });
|
|
|
|
var result = db._query(
|
|
"FOR adoc IN AnotherUnitTestsCollection" +
|
|
" FOR doc IN VIEW UnitTestsView FILTER adoc.id == doc.c && STARTS_WITH(doc['a'], adoc.a) " +
|
|
"SORT TFIDF(doc) DESC, BM25(doc) DESC, doc.a DESC, doc.b " +
|
|
"RETURN doc"
|
|
, null, { waitForSync: true }).toArray();
|
|
|
|
assertEqual(result.length, expected.length);
|
|
var i = 0;
|
|
result.forEach(function(res) {
|
|
var doc = expected[i++];
|
|
assertEqual(doc.a, res.a);
|
|
assertEqual(doc.b, res.b);
|
|
assertEqual(doc.c, res.c);
|
|
});
|
|
},
|
|
};
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief executes the test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
jsunity.run(iResearchAqlTestSuite);
|
|
|
|
return jsunity.done();
|