mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:arangodb/arangodb into devel
This commit is contained in:
commit
d6e2e69fb0
|
@ -12,29 +12,46 @@ meaning that an optimization should not modify the result of a query. A notable
|
|||
to this is that the optimizer is allowed to change the order of results for queries that
|
||||
do not explicitly specify how results should be sorted.
|
||||
|
||||
|
||||
!SUBSECTION Execution plans
|
||||
|
||||
The `explain` command can be used to query the optimal executed plan or even all plans
|
||||
the optimizer has generated. Additionally, `explain` can reveal some more information
|
||||
about the optimizer's view of the query.
|
||||
|
||||
Here's an example that shows the execution plan for a simple query, using the `explain`
|
||||
method of `ArangoStatement`:
|
||||
!SUBSECTION Inspecting plans using the explain helper
|
||||
|
||||
@startDocuBlockInline AQLEXP_01_explainCreate
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{AQLEXP_01_explainCreate}
|
||||
The `explain` method of `ArangoStatement` as shown in the next chapters creates very verbose output.
|
||||
You can work on the output programaticaly, or use this handsome tool that we created
|
||||
to generate a more human readable representation.
|
||||
|
||||
You may use it like this: (we disable syntax highlighting here)
|
||||
|
||||
@startDocuBlockInline AQLEXP_01_axplainer
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{AQLEXP_01_axplainer}
|
||||
~addIgnoreCollection("test")
|
||||
db._create("test");
|
||||
for (i = 0; i < 100; ++i) { db.test.save({ value: i }); }
|
||||
db.test.ensureIndex({ type: "skiplist", fields: [ "value" ] });
|
||||
var explain = require("org/arangodb/aql/explainer").explain;
|
||||
explain("FOR i IN test FILTER i.value > 97 SORT i.value RETURN i.value", {colors:false});
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock AQLEXP_01_axplainer
|
||||
|
||||
|
||||
!SUBSECTION Execution plans in detail
|
||||
|
||||
Lets have a look at the raw json output of the same execution plan
|
||||
using the `explain` method of `ArangoStatement`:
|
||||
|
||||
@startDocuBlockInline AQLEXP_01_explainCreate
|
||||
@EXAMPLE_ARANGOSH_OUTPUT{AQLEXP_01_explainCreate}
|
||||
stmt = db._createStatement("FOR i IN test FILTER i.value > 97 SORT i.value RETURN i.value");
|
||||
stmt.explain();
|
||||
@END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
@endDocuBlock AQLEXP_01_explainCreate
|
||||
|
||||
The result details will be very verbose so they are not shown here in full. Instead,
|
||||
let's take a closer look at the results step by step.
|
||||
The as you can see, result details are very verbose so we will not shown them in full in the next
|
||||
sections. Instead, lets take a closer look at the results step by step.
|
||||
|
||||
!SUBSUBSECTION Execution nodes
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
arangosh> db._create(<span class="hljs-string">"test"</span>);
|
||||
[ArangoCollection <span class="hljs-number">1092291992475</span>, <span class="hljs-string">"test"</span> (type <span class="hljs-built_in">document</span>, status loaded)]
|
||||
arangosh> <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < <span class="hljs-number">100</span>; ++i) { db.test.save({ value: i }); }
|
||||
arangosh> db.test.ensureSkiplist(<span class="hljs-string">"value"</span>);
|
||||
{
|
||||
<span class="hljs-string">"id"</span> : <span class="hljs-string">"test/1092311980955"</span>,
|
||||
<span class="hljs-string">"type"</span> : <span class="hljs-string">"skiplist"</span>,
|
||||
<span class="hljs-string">"fields"</span> : [
|
||||
<span class="hljs-string">"value"</span>
|
||||
],
|
||||
<span class="hljs-string">"unique"</span> : <span class="hljs-literal">false</span>,
|
||||
<span class="hljs-string">"sparse"</span> : <span class="hljs-literal">false</span>,
|
||||
<span class="hljs-string">"isNewlyCreated"</span> : <span class="hljs-literal">true</span>,
|
||||
<span class="hljs-string">"code"</span> : <span class="hljs-number">201</span>
|
||||
}
|
||||
arangosh> <span class="hljs-keyword">var</span> explain = <span class="hljs-built_in">require</span>(<span class="hljs-string">"org/arangodb/aql/explainer"</span>).explain;
|
||||
arangosh> explain(<span class="hljs-string">"FOR i IN test FILTER i.value > 97 SORT i.value RETURN i.value"</span>, {colors:<span class="hljs-literal">false</span>});
|
||||
Query string:
|
||||
FOR i IN test FILTER i.value > <span class="hljs-number">97</span> SORT i.value RETURN i.value
|
||||
|
||||
Execution plan:
|
||||
Id NodeType Est. Comment
|
||||
<span class="hljs-number">1</span> SingletonNode <span class="hljs-number">1</span> * ROOT
|
||||
<span class="hljs-number">9</span> IndexNode <span class="hljs-number">50</span> - FOR i IN test <span class="hljs-comment">/* skiplist index scan */</span>
|
||||
<span class="hljs-number">5</span> CalculationNode <span class="hljs-number">50</span> - LET #<span class="hljs-number">3</span> = i.<span class="hljs-string">`value`</span> <span class="hljs-comment">/* attribute expression */</span> <span class="hljs-comment">/* collections used: i : test */</span>
|
||||
<span class="hljs-number">8</span> ReturnNode <span class="hljs-number">50</span> - RETURN #<span class="hljs-number">3</span>
|
||||
|
||||
Indexes used:
|
||||
By Type Collection Unique Sparse Selectivity Fields Ranges
|
||||
<span class="hljs-number">9</span> skiplist test <span class="hljs-literal">false</span> <span class="hljs-literal">false</span> n/a [ <span class="hljs-string">`value`</span> ] i.<span class="hljs-string">`value`</span> > <span class="hljs-number">97</span>
|
||||
|
||||
Optimization rules applied:
|
||||
Id RuleName
|
||||
<span class="hljs-number">1</span> move-calculations-up
|
||||
<span class="hljs-number">2</span> move-filters-up
|
||||
<span class="hljs-number">3</span> remove-redundant-calculations
|
||||
<span class="hljs-number">4</span> remove-unnecessary-calculations
|
||||
<span class="hljs-number">5</span> move-calculations-up-<span class="hljs-number">2</span>
|
||||
<span class="hljs-number">6</span> move-filters-up-<span class="hljs-number">2</span>
|
||||
<span class="hljs-number">7</span> use-indexes
|
||||
<span class="hljs-number">8</span> remove-filter-covered-by-index
|
||||
<span class="hljs-number">9</span> use-index-<span class="hljs-keyword">for</span>-sort
|
||||
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
arangosh> <span class="hljs-keyword">var</span> examples = <span class="hljs-built_in">require</span>(<span class="hljs-string">"org/arangodb/graph-examples/example-graph.js"</span>);
|
||||
arangosh> <span class="hljs-keyword">var</span> g = examples.loadGraph(<span class="hljs-string">"knows_graph"</span>);
|
||||
arangosh> db.persons.toArray()
|
||||
[
|
||||
{
|
||||
<span class="hljs-string">"name"</span> : <span class="hljs-string">"Charlie"</span>,
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"persons/charlie"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092164590491"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"charlie"</span>
|
||||
},
|
||||
{
|
||||
<span class="hljs-string">"name"</span> : <span class="hljs-string">"Bob"</span>,
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"persons/bob"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092164328347"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"bob"</span>
|
||||
},
|
||||
{
|
||||
<span class="hljs-string">"name"</span> : <span class="hljs-string">"Eve"</span>,
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"persons/eve"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092164983707"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"eve"</span>
|
||||
},
|
||||
{
|
||||
<span class="hljs-string">"name"</span> : <span class="hljs-string">"Dave"</span>,
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"persons/dave"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092164787099"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"dave"</span>
|
||||
},
|
||||
{
|
||||
<span class="hljs-string">"name"</span> : <span class="hljs-string">"Alice"</span>,
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"persons/alice"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092164131739"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"alice"</span>
|
||||
}
|
||||
]
|
||||
arangosh> db.knows.toArray();
|
||||
[
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"knows/1092165835675"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092165835675"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"1092165835675"</span>,
|
||||
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"persons/eve"</span>,
|
||||
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"persons/alice"</span>
|
||||
},
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"knows/1092165639067"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092165639067"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"1092165639067"</span>,
|
||||
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"persons/bob"</span>,
|
||||
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"persons/dave"</span>
|
||||
},
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"knows/1092165245851"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092165245851"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"1092165245851"</span>,
|
||||
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"persons/alice"</span>,
|
||||
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"persons/bob"</span>
|
||||
},
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"knows/1092165442459"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092165442459"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"1092165442459"</span>,
|
||||
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"persons/bob"</span>,
|
||||
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"persons/charlie"</span>
|
||||
},
|
||||
{
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"knows/1092166032283"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092166032283"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"1092166032283"</span>,
|
||||
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"persons/eve"</span>,
|
||||
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"persons/bob"</span>
|
||||
}
|
||||
]
|
||||
arangosh> examples.dropGraph(<span class="hljs-string">"knows_graph"</span>);
|
||||
<span class="hljs-literal">true</span>
|
|
@ -0,0 +1,69 @@
|
|||
arangosh> <span class="hljs-keyword">var</span> examples = <span class="hljs-built_in">require</span>(<span class="hljs-string">"org/arangodb/graph-examples/example-graph.js"</span>);
|
||||
arangosh> <span class="hljs-keyword">var</span> graph = examples.loadGraph(<span class="hljs-string">"social"</span>);
|
||||
arangosh> db.female.toArray()
|
||||
[
|
||||
{
|
||||
<span class="hljs-string">"name"</span> : <span class="hljs-string">"Diana"</span>,
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"female/diana"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092171340699"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"diana"</span>
|
||||
},
|
||||
{
|
||||
<span class="hljs-string">"name"</span> : <span class="hljs-string">"Alice"</span>,
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"female/alice"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092170619803"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"alice"</span>
|
||||
}
|
||||
]
|
||||
arangosh> db.male.toArray()
|
||||
[
|
||||
{
|
||||
<span class="hljs-string">"name"</span> : <span class="hljs-string">"Bob"</span>,
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"male/bob"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092170947483"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"bob"</span>
|
||||
},
|
||||
{
|
||||
<span class="hljs-string">"name"</span> : <span class="hljs-string">"Charly"</span>,
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"male/charly"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092171144091"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"charly"</span>
|
||||
}
|
||||
]
|
||||
arangosh> db.relation.toArray()
|
||||
[
|
||||
{
|
||||
<span class="hljs-string">"type"</span> : <span class="hljs-string">"friend"</span>,
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"relation/bobAndDiana"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092172323739"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"bobAndDiana"</span>,
|
||||
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"male/bob"</span>,
|
||||
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"female/diana"</span>
|
||||
},
|
||||
{
|
||||
<span class="hljs-string">"type"</span> : <span class="hljs-string">"married"</span>,
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"relation/charlyAndDiana"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092172127131"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"charlyAndDiana"</span>,
|
||||
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"male/charly"</span>,
|
||||
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"female/diana"</span>
|
||||
},
|
||||
{
|
||||
<span class="hljs-string">"type"</span> : <span class="hljs-string">"friend"</span>,
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"relation/aliceAndCharly"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092171930523"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"aliceAndCharly"</span>,
|
||||
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"female/alice"</span>,
|
||||
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"male/charly"</span>
|
||||
},
|
||||
{
|
||||
<span class="hljs-string">"type"</span> : <span class="hljs-string">"married"</span>,
|
||||
<span class="hljs-string">"_id"</span> : <span class="hljs-string">"relation/aliceAndBob"</span>,
|
||||
<span class="hljs-string">"_rev"</span> : <span class="hljs-string">"1092171668379"</span>,
|
||||
<span class="hljs-string">"_key"</span> : <span class="hljs-string">"aliceAndBob"</span>,
|
||||
<span class="hljs-string">"_from"</span> : <span class="hljs-string">"female/alice"</span>,
|
||||
<span class="hljs-string">"_to"</span> : <span class="hljs-string">"male/bob"</span>
|
||||
}
|
||||
]
|
||||
arangosh> examples.dropGraph(<span class="hljs-string">"social"</span>);
|
||||
<span class="hljs-literal">true</span>
|
|
@ -29,7 +29,7 @@ make jslint || exit 1
|
|||
echo
|
||||
echo "$0: testing ArangoDB"
|
||||
|
||||
./scripts/unittest all --skipRanges true --skipTimeCritical true --skipSsl true || exit 1
|
||||
./scripts/unittest all --skipRanges true --skipTimeCritical true --skipSsl true --skipBoost true --skipGeo true || exit 1
|
||||
success=`cat out/UNITTEST_RESULT_EXECUTIVE_SUMMARY.json`
|
||||
if test "$success" == "false"; then
|
||||
exit 1
|
||||
|
|
|
@ -644,6 +644,7 @@ SHELL_SERVER_AQL = @top_srcdir@/js/server/tests/aql-arithmetic.js \
|
|||
@top_srcdir@/js/server/tests/aql-parse.js \
|
||||
@top_srcdir@/js/server/tests/aql-primary-index-noncluster.js \
|
||||
@top_srcdir@/js/server/tests/aql-queries-array.js \
|
||||
@top_srcdir@/js/server/tests/aql-queries-array-nested.js \
|
||||
@top_srcdir@/js/server/tests/aql-queries-collection.js \
|
||||
@top_srcdir@/js/server/tests/aql-queries-fulltext.js \
|
||||
@top_srcdir@/js/server/tests/aql-queries-geo.js \
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
/*jshint globalstrict:false, strict:false, maxlen: 500 */
|
||||
/*global assertEqual, assertFalse, assertTrue, AQL_EXPLAIN, AQL_EXECUTE */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tests for array indexes in AQL
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2015 ArangoDB 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 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2015, ArangoDB GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var jsunity = require("jsunity");
|
||||
var db = require("org/arangodb").db;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function nestedArrayIndexSuite () {
|
||||
var cn = "UnitTestsArray";
|
||||
var c;
|
||||
|
||||
var indexUsed = function (query, bindVars) {
|
||||
var plan = AQL_EXPLAIN(query, bindVars || {}).plan;
|
||||
var nodeTypes = plan.nodes.map(function(node) {
|
||||
return node.type;
|
||||
});
|
||||
return (nodeTypes.indexOf("IndexNode") !== -1);
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
setUp : function () {
|
||||
db._drop(cn);
|
||||
c = db._create(cn);
|
||||
},
|
||||
|
||||
tearDown : function () {
|
||||
db._drop(cn);
|
||||
},
|
||||
|
||||
testNestedSubAttribute : function () {
|
||||
c.insert({ tags: [ { name: "foo" }, { name: "bar" }, { name: "baz" } ] });
|
||||
c.insert({ tags: [ { name: "quux" } ] });
|
||||
c.insert({ tags: [ "foo", "bar", "baz" ] });
|
||||
c.insert({ tags: [ "foobar" ] });
|
||||
c.insert({ tags: [ { name: "foobar" } ] });
|
||||
c.insert({ tags: [ { name: "baz" }, { name: "bark" } ] });
|
||||
c.insert({ tags: [ { name: "baz" }, "bark" ] });
|
||||
c.insert({ tags: [ { name: "q0rk" }, { name: "foo" } ] });
|
||||
|
||||
var query = "FOR doc IN " + cn + " FILTER @value IN doc.tags[*].name RETURN doc";
|
||||
|
||||
var tests = [
|
||||
[ "foo", 2 ],
|
||||
[ "bar", 1 ],
|
||||
[ "baz", 3 ],
|
||||
[ "quux", 1 ],
|
||||
[ "foobar", 1 ],
|
||||
[ "bark", 1 ],
|
||||
[ "q0rk", 1 ],
|
||||
[ "sn0rk", 0 ],
|
||||
[ "Quetzalcoatl", 0 ]
|
||||
];
|
||||
|
||||
tests.forEach(function(value) {
|
||||
var result = AQL_EXECUTE(query, { value: value[0] }).json;
|
||||
assertEqual(value[1], result.length);
|
||||
assertFalse(indexUsed(query, { value: value[0] }));
|
||||
});
|
||||
|
||||
// now try again with an the index
|
||||
c.ensureIndex({ type: "hash", fields: [ "tags[*].name" ] });
|
||||
|
||||
tests.forEach(function(value) {
|
||||
var result = AQL_EXECUTE(query, { value: value[0] }).json;
|
||||
assertEqual(value[1], result.length);
|
||||
assertTrue(indexUsed(query, { value: value[0] }));
|
||||
});
|
||||
},
|
||||
|
||||
testNestedAnotherSubAttribute : function () {
|
||||
c.insert({ persons: [ { name: { first: "Jane", last: "Doe" }, gender: "f" }, { name: { first: "Joe", last: "Public" }, gender: "m" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Jack", last: "White" }, gender: "m" }, { name: { first: "John", last: "Black" }, gender: "m" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Janet", last: "Smith" }, gender: "f" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Jill", last: "Jones" }, gender: "f" }, { name: { first: "Jeff", last: "Jackson" }, gender: "m" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Jimbo", last: "Jonas" }, gender: "m" }, { name: { first: "Jay", last: "Jameson" } } ] });
|
||||
c.insert({ persons: [ { name: { first: "Jack", last: "Rabbit" }, gender: "m" }, { name: { first: "Jane", last: "Jackson" }, gender: "f" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Janet", last: "Black" }, gender: "f" }, { name: { first: "James", last: "Smith" }, gender: "m" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Jill", last: "Doe" }, gender: "f" }, { name: { first: "Jeff", last: "Jones" }, gender: "m" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Janet", last: "Doe" }, gender: "f" }, { name: { first: "Julia", last: "Jones" }, gender: "f" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Jo" } }, { name: { first: "Ji" } } ] });
|
||||
|
||||
var query = "FOR doc IN " + cn + " FILTER @value IN doc.persons[*].gender RETURN doc";
|
||||
|
||||
var tests = [
|
||||
[ "m", 7 ],
|
||||
[ "f", 7 ],
|
||||
[ "", 0 ],
|
||||
[ null, 2 ],
|
||||
[ "Quetzalcoatl", 0 ]
|
||||
];
|
||||
|
||||
tests.forEach(function(value) {
|
||||
var result = AQL_EXECUTE(query, { value: value[0] }).json;
|
||||
assertEqual(value[1], result.length, value);
|
||||
assertFalse(indexUsed(query, { value: value[0] }));
|
||||
});
|
||||
|
||||
// now try again with an index
|
||||
c.ensureIndex({ type: "hash", fields: [ "persons[*].gender" ] });
|
||||
|
||||
tests.forEach(function(value) {
|
||||
var result = AQL_EXECUTE(query, { value: value[0] }).json;
|
||||
assertEqual(value[1], result.length, value);
|
||||
assertTrue(indexUsed(query, { value: value[0] }));
|
||||
});
|
||||
},
|
||||
|
||||
testNestedSubSubAttribute : function () {
|
||||
c.insert({ persons: [ { name: { first: "Jane", last: "Doe" }, gender: "f" }, { name: { first: "Joe", last: "Public" }, gender: "m" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Jack", last: "White" }, gender: "m" }, { name: { first: "John", last: "Black" }, gender: "m" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Janet", last: "Smith" }, gender: "f" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Jill", last: "Jones" }, gender: "f" }, { name: { first: "Jeff", last: "Jackson" }, gender: "m" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Jimbo", last: "Jonas" }, gender: "m" }, { name: { first: "Jay", last: "Jameson" } } ] });
|
||||
c.insert({ persons: [ { name: { first: "Jack", last: "Rabbit" }, gender: "m" }, { name: { first: "Jane", last: "Jackson" }, gender: "f" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Janet", last: "Black" }, gender: "f" }, { name: { first: "James", last: "Smith" }, gender: "m" } ] });
|
||||
c.insert({ persons: [ { name: { first: "Jill", last: "Doe" }, gender: "f" }, { name: { first: "Jeff", last: "Jones" }, gender: "m" } ] });
|
||||
|
||||
var query = "FOR doc IN " + cn + " FILTER @value IN doc.persons[*].name.first RETURN doc";
|
||||
|
||||
var tests = [
|
||||
[ "Jane", 2 ],
|
||||
[ "Joe", 1 ],
|
||||
[ "Jack", 2 ],
|
||||
[ "John", 1 ],
|
||||
[ "Janet", 2 ],
|
||||
[ "Jill", 2 ],
|
||||
[ "Jeff", 2 ],
|
||||
[ "Jimbo", 1 ],
|
||||
[ "Jay", 1 ],
|
||||
[ "James", 1 ],
|
||||
[ "Quetzalcoatl", 0 ]
|
||||
];
|
||||
|
||||
tests.forEach(function(value) {
|
||||
var result = AQL_EXECUTE(query, { value: value[0] }).json;
|
||||
assertEqual(value[1], result.length);
|
||||
assertFalse(indexUsed(query, { value: value[0] }));
|
||||
});
|
||||
|
||||
// now try again with an index
|
||||
c.ensureIndex({ type: "hash", fields: [ "persons[*].name.first" ] });
|
||||
|
||||
tests.forEach(function(value) {
|
||||
var result = AQL_EXECUTE(query, { value: value[0] }).json;
|
||||
assertEqual(value[1], result.length);
|
||||
assertTrue(indexUsed(query, { value: value[0] }));
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
testNestedNestedSubSubAttribute : function () {
|
||||
c.insert({ persons: [ { addresses: [ { country: { name: "DE" } }, { country: { name: "IT" } } ] } ] });
|
||||
c.insert({ persons: [ { addresses: [ { country: { name: "FR" } }, { country: { name: "GB" } } ] } ] });
|
||||
c.insert({ persons: [ ] });
|
||||
c.insert({ persons: [ { addresses: [ ] } ] });
|
||||
c.insert({ persons: [ { addresses: [ { country: { name: "BG" } } ] } ] });
|
||||
c.insert({ persons: [ { addresses: [ { country: { name: "US" } } ] } ] });
|
||||
c.insert({ persons: [ { addresses: [ { country: { } } ] } ] });
|
||||
c.insert({ persons: [ { addresses: [ { country: { name: "RU" } } ] } ] });
|
||||
c.insert({ persons: [ { addresses: [ { country: { name: "PL" } }, { country: { name: "CH" } } ] } ] });
|
||||
c.insert({ persons: [ { addresses: [ { country: { name: "IT" } }, { country: { name: "US" } } ] } ] });
|
||||
c.insert({ persons: [ { addresses: [ { country: { name: "DK" } }, { country: { name: "DE" } } ] } ] });
|
||||
c.insert({ persons: [ { addresses: [ { country: { name: "NL" } }, { country: { name: "BE" } } ] } ] });
|
||||
c.insert({ persons: [ { addresses: [ { country: { name: "GB" } }, { country: { name: "DK" } } ] } ] });
|
||||
c.insert({ persons: [ { addresses: [ { country: { name: "DK" } }, { country: { name: "SE" } }, { country: { name: "SE" } } ] } ] });
|
||||
|
||||
var query = "FOR doc IN " + cn + " FILTER @value IN doc.persons[*].addresses[*].country.name RETURN doc";
|
||||
var query = "FOR doc IN " + cn + " FILTER @value != 'hassan' RETURN doc.persons[*].addresses[*].country.name";
|
||||
|
||||
var tests = [
|
||||
[ "DE", 2 ],
|
||||
[ "IT", 2 ],
|
||||
[ "FR", 1 ],
|
||||
[ "GB", 2 ],
|
||||
[ "BG", 1 ],
|
||||
[ "US", 2 ],
|
||||
[ "RU", 1 ],
|
||||
[ "PL", 1 ],
|
||||
[ "CH", 1 ],
|
||||
[ "DK", 3 ],
|
||||
[ "NL", 1 ],
|
||||
[ "BE", 1 ],
|
||||
[ "SE", 1 ],
|
||||
[ "Quetzalcoatl", 0 ]
|
||||
];
|
||||
|
||||
tests.forEach(function(value) {
|
||||
var result = AQL_EXECUTE(query, { value: value[0] }).json;
|
||||
require("internal").print(result, value);
|
||||
assertEqual(value[1], result.length);
|
||||
assertFalse(indexUsed(query, { value: value[0] }));
|
||||
});
|
||||
|
||||
// now try again with an index
|
||||
c.ensureIndex({ type: "hash", fields: [ "persons[*].addresses[*].country.name" ] });
|
||||
|
||||
tests.forEach(function(value) {
|
||||
var result = AQL_EXECUTE(query, { value: value[0] }).json;
|
||||
assertEqual(value[1], result.length);
|
||||
assertTrue(indexUsed(query, { value: value[0] }));
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
jsunity.run(nestedArrayIndexSuite);
|
||||
|
||||
return jsunity.done();
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
Loading…
Reference in New Issue