1
0
Fork 0

Doc - ArangoSearch documentation update (#6323)

This commit is contained in:
Tobias Gödderz 2018-09-05 18:17:45 +02:00 committed by sleto-it
parent 0635adec56
commit a540042445
45 changed files with 1125 additions and 521 deletions

View File

@ -191,9 +191,9 @@ FOR u IN users
INSERT u IN backup INSERT u IN backup
``` ```
As a final example, let's find some documents in collection *users* and Subsequently, let's find some documents in collection *users* and remove them
remove them from collection *backup*. The link between the documents in both from collection *backup*. The link between the documents in both collections is
collections is established via the documents' keys: established via the documents' keys:
```js ```js
FOR u IN users FOR u IN users
@ -201,6 +201,14 @@ FOR u IN users
REMOVE u IN backup REMOVE u IN backup
``` ```
The following example will remove all documents from both *users* and *backup*:
```js
LET r1 = (FOR u IN users REMOVE u IN users)
LET r2 = (FOR u IN backup REMOVE u IN backup)
RETURN true
```
### Returning documents ### Returning documents
Data-modification queries can optionally return documents. In order to reference Data-modification queries can optionally return documents. In order to reference
@ -286,13 +294,12 @@ must be known to the AQL executor at query-compile time and cannot change at
runtime. Using a bind parameter to specify the runtime. Using a bind parameter to specify the
[collection name](../Manual/Appendix/Glossary.html#collection-name) is allowed. [collection name](../Manual/Appendix/Glossary.html#collection-name) is allowed.
Data-modification operations are restricted to one collection at a time. It is It is not possible to use multiple data-modification operations for the same
not possible to use multiple data-modification operations for the same collection collection in the same query, or follow up a data-modification operation for a
in the same query, or follow up a data-modification operation for a specific specific collection with a read operation for the same collection. Neither is
collection with a read operation for the same collection. Neither is it possible it possible to follow up any data-modification operation with a traversal query
to follow up any data-modification operation with a traversal query (which may (which may read from arbitrary collections not necessarily known at the start of
read from arbitrary collections not necessarily known at the start of the the traversal).
traversal).
That means you may not place several `REMOVE` or `UPDATE` statements for the same That means you may not place several `REMOVE` or `UPDATE` statements for the same
collection into the same query. It is however possible to modify different collections collection into the same query. It is however possible to modify different collections

View File

@ -170,7 +170,7 @@ FOR f IN ´filter´
Collection names can be used in queries as they are. If a collection happens to Collection names can be used in queries as they are. If a collection happens to
have the same name as a keyword, the name must be enclosed in backticks. have the same name as a keyword, the name must be enclosed in backticks.
Please refer to the [Naming Conventions in ArangoDB](../../Manual/DataModeling/NamingConventions/CollectionNames.html) Please refer to the [Naming Conventions in ArangoDB](../../Manual/DataModeling/NamingConventions/CollectionAndViewNames.html)
about collection naming conventions. about collection naming conventions.
AQL currently has a limit of up to 256 collections used in one AQL query. AQL currently has a limit of up to 256 collections used in one AQL query.

View File

@ -16,6 +16,16 @@ FOR vertexVariableName, edgeVariableName, pathVariableName IN traversalExpressio
``` ```
For this special case see [the graph traversals chapter](../Graphs/Traversals.md). For this special case see [the graph traversals chapter](../Graphs/Traversals.md).
For views, there is a special (optional) `SEARCH` keyword:
```js
FOR variableName IN viewName SEARCH searchExpression
```
Details can be found in [the views chapter](../Views/README.md).
For all other cases read on: For all other cases read on:
Each array element returned by *expression* is visited exactly once. It is Each array element returned by *expression* is visited exactly once. It is

View File

@ -1,7 +1,7 @@
ArangoSearch Views in AQL ArangoSearch Views in AQL
========================= =========================
Views of type **arangosearch** are an integration layer meant to seamlessly Views of type `arangosearch` are an integration layer meant to seamlessly
integrate with and natively expose the full power of the integrate with and natively expose the full power of the
[IResearch library](https://github.com/iresearch-toolkit/iresearch) [IResearch library](https://github.com/iresearch-toolkit/iresearch)
to the ArangoDB user. to the ArangoDB user.
@ -11,6 +11,167 @@ They provide the capability to:
* search documents based on AQL boolean expressions and functions * search documents based on AQL boolean expressions and functions
* sort the result set based on how closely each document matched the search * sort the result set based on how closely each document matched the search
Overview and Significance
-------------------------
Looking up documents in an ArangoSearch View is done via the `FOR` keyword:
```js
FOR doc IN someView
...
```
`FOR` operations over ArangoSearch Views have an additional, optional, `SEARCH`
keyword:
```js
FOR doc IN someView
SEARCH searchExpression
```
### SEARCH
`SEARCH` expressions look a lot like `FILTER` operations, but have some noteable
differences.
First of all, filters and functions in `SEARCH`, when applied to documents
_emitted from an ArangoSearch View_, work _only_ on attributes linked in the
view.
For example, given a collection `myCol` with the following documents:
```js
[
{ someAttr: 'One', anotherAttr: 'One' },
{ someAttr: 'Two', anotherAttr: 'Two' }
]
```
with a view, where `someAttr` is indexed by the following view `myView`:
```js
{
"type": "arangosearch",
"links": {
"myCol": {
"fields": {
"someAttr": {}
}
}
}
}
```
Then, a search on `someAttr` yields the following result:
```js
FOR doc IN myView
SEARCH doc.someAttr == 'One'
RETURN doc
```
```js
[ { someAttr: 'One', anotherAttr: 'One' } ]
```
While a search on `anotherAttr` yields an empty result:
```js
FOR doc IN myView
SEARCH doc.anotherAttr == 'One'
RETURN doc
```
```js
[]
```
- This only applies to the expression after the `SEARCH` keyword.
- This only applies to tests regarding documents emitted from a view. Other
tests are not affected.
- In order to use `SEARCH` using all attributes of a linked sources, the special
`includeAllFields` [link property](../../../Manual/Views/ArangoSearch/DetailedOverview.html#link-properties) was desinged.
### SORT
The document search via the `SEARCH` keyword and the sorting via the
ArangoSearch functions, namely `BM25()` and `TFIDF()`, are closely intertwined.
The query given in the `SEARCH` expression is not only used to filter documents,
but also is used with the sorting functions to decide which document matches
the query best. Other documents in the view also affect this decision.
Therefore the ArangoSearch sorting functions can work _only_ on documents
emitted from a view, as both the corresponding `SEARCH` expression and the view
itself are consulted in order to sort the results.
The `BOOST()` function, described below, can be used to fine-tune the resulting
ranking by weighing sub-expressions in `SEARCH` differently.
### Arrays and trackListPositions
Unless [**trackListPositions**](../../../Manual/Views/ArangoSearch/DetailedOverview.html#link-properties)
is set to `true`, which it is not by default, arrays behave differently. Namely
they behave like a disjunctive superposition of their values - this is best
shown with an example.
With `trackListPositions: false`, which is the default, and given a document
`doc` containing
```js
{ attr: [ 'valueX', 'valueY', 'valueZ' ] }
```
in a `SEARCH` clause, the expression
```js
doc.attr == 'valueX'
```
will be true, as will be
```js
doc.attr == 'valueY'
```
and `== valueZ`. With `trackListPositions: true`,
```js
doc.attr[0] == 'valueX'
```
would work as usual.
### Comparing analyzed fields
As described in [value analysis](#arangosearch-value-analysis), when a field is
processed by a specific analyzer, comparison tests are done per word. For
example, given the field `text` is analyzed with `"text_en"` and contains the
string `"a quick brown fox jumps over the lazy dog"`, the following expression
will be true:
```js
ANALYZER(d.text == 'fox', "text_en")
```
Note also, that the words analyzed in the text are stemmed, so this is also
true:
```js
ANALYZER(d.text == 'jump', "text_en")
```
So a comparison will actually test if a word is contained in the text. With
`trackListPositions: false`, this means for arrays if the word is contained in
any element of the array. For example, given
```js
d.text = [ "a quick", "brown fox", "jumps over the", "lazy dog"]
```
the following will be true:
```js
ANALYZER(d.text == 'jump', "text_en")
```
ArangoSearch value analysis ArangoSearch value analysis
--------------------------- ---------------------------
@ -36,55 +197,58 @@ e.g. to match docs with 'word == quick' OR 'word == brown' OR 'word == fox'
FOR doc IN someCollection FOR doc IN someCollection
FILTER doc.word IN TOKENS('a quick brown fox', 'text_en') FILTER doc.word IN TOKENS('a quick brown fox', 'text_en')
RETRUN doc RETURN doc
ArangoSearch filters ArangoSearch filters
-------------------- --------------------
The basic ArangoSearch functionality can be accessed via SEARCH statement with The basic ArangoSearch functionality can be accessed via the `SEARCH` statement
common AQL filters and operators, e.g.: with common AQL filters and operators, e.g.:
- *AND* ```
- *OR* - `AND`
- *NOT* - `OR`
- *==* - `NOT`
- *<=* - `==`
- *>=* - `<=`
- *<* - `>=`
- *>* - `<`
- *!=* - `>`
- *IN <ARRAY>* - `!=`
- *IN <RANGE>* - `IN <ARRAY>`
- `IN <RANGE>`
```
However, the full power of ArangoSearch is harnessed and exposed via functions, However, the full power of ArangoSearch is harnessed and exposed via functions,
during both the search and sort stages. during both the search and sort stages.
Note, that SEARCH statement is meant to be treated as a part of the Note, that `SEARCH` statement, in contrast to `FILTER`, is meant to be treated
expression, but not as an individual statement in contrast to FILTER as a part of the `FOR` operation, not as an individual statement.
The supported AQL context functions are: The supported AQL context functions are:
### ANALYZER() ### ANALYZER()
`ANALYZER(search-expression, analyzer)` `ANALYZER(searchExpression, analyzer)`
Override analyzer in a context of **search-expression** with another one, denoted Override analyzer in a context of **searchExpression** with another one,
by a specified **analyzer** argument, making it available for search functions. denoted by a specified **analyzer** argument, making it available for search
functions.
- *search-expression* - any valid search expression - *searchExpression* - any valid search expression
- *analyzer* - string with the analyzer to imbue, i.e. *"text_en"* or one of the other - *analyzer* - string with the analyzer to imbue, i.e. *"text_en"* or one of the
[available string analyzers](../../../Manual/Views/ArangoSearch/Analyzers.html) other [available string analyzers](../../../Manual/Views/ArangoSearch/Analyzers.html)
By default, context contains `Identity` analyzer. By default, context contains `Identity` analyzer.
### BOOST() ### BOOST()
`BOOST(search-expression, boost)` `BOOST(searchExpression, boost)`
Override boost in a context of **search-expression** with a specified value, Override boost in a context of **searchExpression** with a specified value,
making it available for scorer functions. making it available for scorer functions.
- *search-expression* - any valid search expression - *searchExpression* - any valid search expression
- *boost* - numeric boost value - *boost* - numeric boost value
By default, context contains boost value equal to `1.0`. By default, context contains boost value equal to `1.0`.
@ -93,28 +257,36 @@ The supported search functions are:
### EXISTS() ### EXISTS()
Note: Will only match **attribute-name** values that have been processed with Note: Will only match values when the specified attribute has been processed
the link property **storeValues** set to anything other than **none**. with the link property **storeValues** set to **"id"** (by default it's
**"none"**).
`EXISTS(attribute-name)` `EXISTS(doc.someAttr)`
Match documents where the attribute **attribute-name** exists in the document. Match documents **doc** where the attribute **someAttr** exists in the
document.
`EXISTS(attribute-name, "analyzer" [, analyzer])` This also works with sub-attributes, e.g.
Match documents where the **attribute-name** exists in the document and `EXISTS(doc.someAttr.anotherAttr)`
was indexed by the specified **analyzer**.
In case if **analyzer** isn't specified, current context analyzer (e.g. specified by
`ANALYZER` function) will be used.
`EXISTS(attribute-name, type)` as long as the field is processed by the view with **storeValues** not
**none**.
Match documents where the **attribute-name** exists in the document `EXISTS(doc.someAttr, "analyzer", analyzer)`
Match documents where **doc.someAttr** exists in the document _and_ was indexed
by the specified **analyzer**. **analyzer** is optional and defaults to the
current context analyzer (e.g. specified by `ANALYZER` function).
`EXISTS(doc.someAttr, type)`
Match documents where the **doc.someAttr** exists in the document
and is of the specified type. and is of the specified type.
- *attribute-name* - the path of the attribute to exist in the document - *doc.someAttr* - the path of the attribute to exist in the document
- *analyzer* - string with the analyzer used, i.e. *"text_en"* or one of the other - *analyzer* - string with the analyzer used, i.e. *"text_en"* or one of the
[available string analyzers](../../../Manual/Views/ArangoSearch/Analyzers.html) other [available string analyzers](../../../Manual/Views/ArangoSearch/Analyzers.html)
- *type* - data type as string; one of: - *type* - data type as string; one of:
- **bool** - **bool**
- **boolean** - **boolean**
@ -122,57 +294,84 @@ Match documents where the **attribute-name** exists in the document
- **null** - **null**
- **string** - **string**
In case if **analyzer** isn't specified, current context analyzer (e.g. specified by In case if **analyzer** isn't specified, current context analyzer (e.g.
`ANALYZER` function) will be used. specified by `ANALYZER` function) will be used.
### PHRASE() ### PHRASE()
``` ```
PHRASE(attribute-name, PHRASE(doc.someAttr,
phrasePart [, skipTokens, phrasePart [, ... skipTokens, phrasePart]] phrasePart [, skipTokens] [, phrasePart | , phrasePart, skipTokens]*
[, analyzer]) [, analyzer])
``` ```
Search for a phrase in the referenced attributes. Search for a phrase in the referenced attributes.
The phrase can be expressed as an arbitrary number of *phraseParts* separated by *skipToken* number of tokens. The phrase can be expressed as an arbitrary number of *phraseParts* separated by
*skipToken* number of tokens.
- *attribute-name* - the path of the attribute to compare against in the document - *doc.someAttr* - the path of the attribute to compare against in the document
- *phrasePart* - a string to search in the token stream; may consist of several words; will be split using the specified *analyzer* - *phrasePart* - a string to search in the token stream; may consist of several
words; will be split using the specified *analyzer*
- *skipTokens* number of words or tokens to treat as wildcards - *skipTokens* number of words or tokens to treat as wildcards
- *analyzer* - string with the analyzer used, i.e. *"text_en"* or one of the other - *analyzer* - string with the analyzer used, i.e. *"text_en"* or one of the
[available string analyzers](../../../Manual/Views/ArangoSearch/Analyzers.html) other [available string analyzers
](../../../Manual/Views/ArangoSearch/Analyzers.html)
For example, given a document `doc` containing the text `"Lorem ipsum dolor sit
amet, consectetur adipiscing elit"`, the following expression will be `true`:
```js
PHRASE(doc.text, "ipsum", 1, "sit", 2, "adipiscing", "text_de")
```
Specifying deep attributes like `doc.some.deep.attr` is also allowed. The
attribute has to be processed by the view as specified in the link.
### STARTS_WITH() ### STARTS_WITH()
`STARTS_WITH(attribute-name, prefix)` `STARTS_WITH(doc.someAttr, prefix)`
Match the value of the **attribute-name** that starts with **prefix** Match the value of the **doc.someAttr** that starts with **prefix**
- *attribute-name* - the path of the attribute to compare against in the document - *doc.someAttr* - the path of the attribute to compare against in the document
- *prefix* - a string to search at the start of the text - *prefix* - a string to search at the start of the text
Specifying deep attributes like `doc.some.deep.attr` is also allowed. The
attribute has to be processed by the view as specified in the link.
### TOKENS() ### TOKENS()
`TOKENS(input, analyzer)` `TOKENS(input, analyzer)`
Split the **input** string with the help of the specified **analyzer** into an Array. Split the **input** string with the help of the specified **analyzer** into an
The resulting Array can i.e. be used in subsequent `FILTER` or `SEARCH` statements with the **IN** operator. Array. The resulting Array can i.e. be used in subsequent `FILTER` or `SEARCH`
This can be used to better understand how the specific analyzer is going to behave. statements with the **IN** operator. This can be used to better understand how
the specific analyzer is going to behave.
- *input* string to tokenize - *input* string to tokenize
- *analyzer* one of the [available string analyzers](../../../Manual/Views/ArangoSearch/Analyzers.html) - *analyzer* one of the [available string_analyzers](../../../Manual/Views/ArangoSearch/Analyzers.html)
### MIN_MATCH() ### MIN_MATCH()
`MIN_MATCH(search-expression, [..., search-expression], min-match-count)` `MIN_MATCH(searchExpression [, searchExpression]*, minMatchCount)`
Match documents where at least **min-match-count** of the specified **search-expression**s Match documents where at least **minMatchCount** of the specified
are satisfied. **searchExpression**s are satisfied.
- *search-expression* - any valid search expression - *searchExpression* - any valid search expression
- *min-match-count* - minimum number of search-expressions that should be satisfied - *minMatchCount* - minimum number of *searchExpression*s that should be
satisfied
#### Searching examples For example,
```js
MIN_MATCH(doc.text == 'quick', doc.text == 'brown', doc.text == 'fox', 2)
```
if `doc.text`, as analyzed by the current analyzer, contains 2 out of 'quick',
'brown' and 'fox', it will be included as matched one.
### Searching examples
to match documents which have a 'name' attribute to match documents which have a 'name' attribute
@ -275,47 +474,98 @@ to match documents where 'description' best matches 'a quick brown fox'
FOR doc IN someView SEARCH ANALYZER(doc.description IN TOKENS('a quick brown fox', 'text_en'), 'text_en') FOR doc IN someView SEARCH ANALYZER(doc.description IN TOKENS('a quick brown fox', 'text_en'), 'text_en')
RETURN doc RETURN doc
ArangoSearch sort ArangoSearch sorting
----------------- --------------------
A major feature of ArangoSearch views is their capability of sorting results A major feature of ArangoSearch Views is their capability of sorting results
based on the creation-time search conditions and zero or more sorting functions. based on the creation-time search conditions and zero or more sorting functions.
The sorting functions are meant to be user-defined. The ArangoSearch sorting functions available are `TFIDF()` and `BM25()`.
Note: Similar to other sorting functions on regular collections the first Note: The first argument to any ArangoSearch sorting function is _always_ the
argument to any sorting function is _always_ either the document emitted by document emitted by a `FOR` operation over an ArangoSearch View.
the `FOR` statement, or some sub-attribute of it.
The sorting functions are meant to be user-defined. The following functions are already built in: Note: An ArangoSearch sorting function is _only_ allowed as an argument to a
`SORT` operation. But they can be mixed with other arguments to `SORT`.
So the following examples are valid:
```js
FOR doc IN someView
SORT TFIDF(doc)
```
```js
FOR a IN viewA
FOR b IN viewB
SORT BM25(a), TFIDF(b)
```
```js
FOR a IN viewA
FOR c IN someCollection
FOR b IN viewB
SORT TFIDF(b), c.name, BM25(a)
```
while these will _not_ work:
```js
FOR doc IN someCollection
SORT TFIDF(doc) // !!! Error
```
```js
FOR doc IN someCollection
RETURN BM25(doc) // !!! Error
```
```js
FOR doc IN someCollection
SORT BM25(doc.someAttr) // !!! Error
```
```js
FOR doc IN someView
SORT TFIDF("someString") // !!! Error
```
```js
FOR doc IN someView
SORT BM25({some: obj}) // !!! Error
```
The following sorting methods are available:
### Literal sorting ### Literal sorting
You can sort documents by simply specifying the *attribute-name* directly, as you do using indices in other places. You can sort documents by simply specifying arbitrary values or expressions, as
you do in other places.
### Best Matching 25 Algorithm ### BM25()
`BM25(attribute-name, [k, [b]])` `BM25(doc, k, b)`
- *k* (number, _optional_): calibrates the text term frequency scaling, the default is
_1.2_. A *k* value of _0_ corresponds to a binary model (no term frequency), and a large
value corresponds to using raw term frequency
- *b* (number, _optional_): determines the scaling by the total text length, the default
is _0.75_. At the extreme values of the coefficient *b*, BM25 turns into ranking
functions known as BM11 (for *b* = `1`, corresponds to fully scaling the term weight by
the total text length) and BM15 (for *b* = `0`, corresponds to no length normalization)
Sorts documents using the [**Best Matching 25** algorithm](https://en.wikipedia.org/wiki/Okapi_BM25). Sorts documents using the [**Best Matching 25** algorithm](https://en.wikipedia.org/wiki/Okapi_BM25).
See the [`BM25()` section in ArangoSearch Scorers](../../../Manual/Views/ArangoSearch/Scorers.html)
for details.
Optionally the term frequency **k** and coefficient **b** of the algorithm can be specified as floating point numbers: ### TFIDF()
- *k* defaults to `1.2`; *k* calibrates the text term frequency scaling. `TFIDF(doc, withNorms)`
A *k* value of *0* corresponds to a binary model (no term frequency),
and a large value corresponds to using raw term frequency.
- *b* defaults to `0.75`; *b* determines the scaling by the total text length. - *doc* (document): must be emitted by `FOR doc IN someView`
- b = 1 corresponds to fully scaling the term weight by the total text length - *withNorms* (bool, _optional_): specifying whether scores should be
- b = 0 corresponds to no length normalization. normalized, the default is _false_
At the extreme values of the coefficient *b*, BM25 turns into ranking functions known as BM11 (for b = 1) and BM15 (for b = 0). Sorts documents using the
[**term frequencyinverse document frequency** algorithm](https://en.wikipedia.org/wiki/TF-IDF).
See the
[`TFIDF()` section in ArangoSearch Scorers](../../../Manual/Views/ArangoSearch/Scorers.html)
for details.
### Term Frequency Inverse Document Frequency Algorithm
`TFIDF(attribute-name, [with-norms])`
Sorts documents using the [**term frequencyinverse document frequency** algorithm](https://en.wikipedia.org/wiki/TF-IDF).
optionally specifying that norms should be used via **with-norms**
### Sorting examples ### Sorting examples

View File

@ -4,10 +4,22 @@ Views in AQL
Conceptually a **view** is just another document data source, similar to an Conceptually a **view** is just another document data source, similar to an
array or a document/edge collection, e.g.: array or a document/edge collection, e.g.:
FOR doc IN exampleView ```js
FOR doc IN exampleView SEARCH ...
FILTER ... FILTER ...
SORT ... SORT ...
RETURN ... RETURN ...
```
Other than collections, views have an additional but optional `SEARCH` keyword:
```js
FOR doc IN exampleView
SEARCH ...
FILTER ...
SORT ...
RETURN ...
```
A view is meant to be an abstraction over a transformation applied to documents A view is meant to be an abstraction over a transformation applied to documents
of zero or more collections. The transformation is view-implementation specific of zero or more collections. The transformation is view-implementation specific
@ -17,6 +29,5 @@ represent all documents available in the specified set of collections.
Views can be defined and administered on a per view-type basis via Views can be defined and administered on a per view-type basis via
the [web interface](../../Manual/Programs/WebInterface/index.html). the [web interface](../../Manual/Programs/WebInterface/index.html).
The currently supported view implementations are: Currently there is a single supported view implementation, namely
`arangosearch` as described in [ArangoSearch View](ArangoSearch/README.md).
- **arangosearch** as described in [ArangoSearch View](ArangoSearch/README.md)

View File

@ -14,7 +14,7 @@ Returns a _ArangoSearchView_ instance for the given view name.
- **viewName**: `string` - **viewName**: `string`
Name of the arangosearch view. Name of the `arangosearch` view.
**Examples** **Examples**

View File

@ -73,8 +73,8 @@ Creates a collection with the given _options_ for this collection's name, then r
```Java ```Java
ArangoDB arango = new ArangoDB.Builder().build(); ArangoDB arango = new ArangoDB.Builder().build();
ArangoDatabase db = arango.db("myDB"); ArangoDatabase db = arango.db("myDB");
db.createCollection("potatos", new CollectionCreateOptions()); db.createCollection("potatoes", new CollectionCreateOptions());
// the document collection "potatos" now exists // the document collection "potatoes" now exists
``` ```
## ArangoCollection.create ## ArangoCollection.create
@ -144,9 +144,9 @@ Alternative for [ArangoDatabase.createCollection](#arangodatabasecreatecollectio
```Java ```Java
ArangoDB arango = new ArangoDB.Builder().build(); ArangoDB arango = new ArangoDB.Builder().build();
ArangoDatabase db = arango.db("myDB"); ArangoDatabase db = arango.db("myDB");
ArangoCollection collection = db.collection("potatos"); ArangoCollection collection = db.collection("potatoes");
collection.create(new CollectionCreateOptions()); collection.create(new CollectionCreateOptions());
// the document collection "potatos" now exists // the document collection "potatoes" now exists
``` ```
## ArangoCollection.load ## ArangoCollection.load

View File

@ -26,7 +26,7 @@ Checks whether the collection exists
```Java ```Java
ArangoDB arango = new ArangoDB.Builder().build(); ArangoDB arango = new ArangoDB.Builder().build();
ArangoDatabase db = arango.db("myDB"); ArangoDatabase db = arango.db("myDB");
ArangoCollection collection = db.collection("potatos"); ArangoCollection collection = db.collection("potatoes");
boolean exists = collection.exists(); boolean exists = collection.exists();
``` ```
@ -44,7 +44,7 @@ Returns information about the collection.
```Java ```Java
ArangoDB arango = new ArangoDB.Builder().build(); ArangoDB arango = new ArangoDB.Builder().build();
ArangoDatabase db = arango.db("myDB"); ArangoDatabase db = arango.db("myDB");
ArangoCollection collection = db.collection("potatos"); ArangoCollection collection = db.collection("potatoes");
CollectionEntity info = collection.getInfo(); CollectionEntity info = collection.getInfo();
``` ```
@ -62,7 +62,7 @@ Reads the properties of the specified collection.
```Java ```Java
ArangoDB arango = new ArangoDB.Builder().build(); ArangoDB arango = new ArangoDB.Builder().build();
ArangoDatabase db = arango.db("myDB"); ArangoDatabase db = arango.db("myDB");
ArangoCollection collection = db.collection("potatos"); ArangoCollection collection = db.collection("potatoes");
CollectionPropertiesEntity properties = collection.getProperties(); CollectionPropertiesEntity properties = collection.getProperties();
``` ```
@ -80,7 +80,7 @@ Retrieve the collections revision.
```Java ```Java
ArangoDB arango = new ArangoDB.Builder().build(); ArangoDB arango = new ArangoDB.Builder().build();
ArangoDatabase db = arango.db("myDB"); ArangoDatabase db = arango.db("myDB");
ArangoCollection collection = db.collection("potatos"); ArangoCollection collection = db.collection("potatoes");
CollectionRevisionEntity revision = collection.getRevision(); CollectionRevisionEntity revision = collection.getRevision();
``` ```
@ -98,7 +98,7 @@ Fetches a list of all indexes on this collection.
```Java ```Java
ArangoDB arango = new ArangoDB.Builder().build(); ArangoDB arango = new ArangoDB.Builder().build();
ArangoDatabase db = arango.db("myDB"); ArangoDatabase db = arango.db("myDB");
ArangoCollection collection = db.collection("potatos"); ArangoCollection collection = db.collection("potatoes");
Collection<IndexEntity> indexes = collection.getIndexes(); Collection<IndexEntity> indexes = collection.getIndexes();
``` ```

View File

@ -32,7 +32,7 @@ ArangoView view = db.view("myView");
ArangoDatabase.arangoSearch(String name) : ArangoSearch ArangoDatabase.arangoSearch(String name) : ArangoSearch
``` ```
Returns a _ArangoSearch_ instance for the given ArangoSearch view name. Returns a _ArangoSearch_ instance for the given ArangoSearch View name.
**Arguments** **Arguments**

View File

@ -2,7 +2,7 @@
# ArangoSearch API # ArangoSearch API
These functions implement the These functions implement the
[HTTP API for ArangoSearch views](../../../..//HTTP/Views/ArangoSearch.html). [HTTP API for ArangoSearch Views](../../../..//HTTP/Views/ArangoSearch.html).
## ArangoDatabase.createArangoSearch ## ArangoDatabase.createArangoSearch
@ -10,7 +10,7 @@ These functions implement the
ArangoDatabase.createArangoSearch(String name, ArangoSearchCreateOptions options) : ViewEntity ArangoDatabase.createArangoSearch(String name, ArangoSearchCreateOptions options) : ViewEntity
``` ```
Creates a ArangoSearch view with the given _options_, then returns view information from the server. Creates a ArangoSearch View with the given _options_, then returns view information from the server.
**Arguments** **Arguments**
@ -41,8 +41,8 @@ Creates a ArangoSearch view with the given _options_, then returns view informat
```Java ```Java
ArangoDB arango = new ArangoDB.Builder().build(); ArangoDB arango = new ArangoDB.Builder().build();
ArangoDatabase db = arango.db("myDB"); ArangoDatabase db = arango.db("myDB");
db.createArangoSearch("potatos", new ArangoSearchPropertiesOptions()); db.createArangoSearch("potatoes", new ArangoSearchPropertiesOptions());
// the ArangoSearch view "potatos" now exists // the ArangoSearch View "potatoes" now exists
``` ```
## ArangoSearch.create ## ArangoSearch.create
@ -51,7 +51,7 @@ db.createArangoSearch("potatos", new ArangoSearchPropertiesOptions());
ArangoSearch.create(ArangoSearchCreateOptions options) : ViewEntity ArangoSearch.create(ArangoSearchCreateOptions options) : ViewEntity
``` ```
Creates a ArangoSearch view with the given _options_, then returns view information from the server. Creates a ArangoSearch View with the given _options_, then returns view information from the server.
Alternative for [ArangoDatabase.createArangoSearch](#arangodatabasecreatearangosearch). Alternative for [ArangoDatabase.createArangoSearch](#arangodatabasecreatearangosearch).
@ -80,10 +80,10 @@ Alternative for [ArangoDatabase.createArangoSearch](#arangodatabasecreatearangos
```Java ```Java
ArangoDB arango = new ArangoDB.Builder().build(); ArangoDB arango = new ArangoDB.Builder().build();
ArangoDatabase db = arango.db("myDB"); ArangoDatabase db = arango.db("myDB");
ArangoSearch view = db.arangoSearch("potatos"); ArangoSearch view = db.arangoSearch("potatoes");
view.create(new ArangoSearchPropertiesOptions()); view.create(new ArangoSearchPropertiesOptions());
// the ArangoSearch view "potatos" now exists // the ArangoSearch View "potatoes" now exists
``` ```
## ArangoSearch.getProperties ## ArangoSearch.getProperties
@ -99,7 +99,7 @@ Reads the properties of the specified view.
```Java ```Java
ArangoDB arango = new ArangoDB.Builder().build(); ArangoDB arango = new ArangoDB.Builder().build();
ArangoDatabase db = arango.db("myDB"); ArangoDatabase db = arango.db("myDB");
ArangoSearch view = db.arangoSearch("potatos"); ArangoSearch view = db.arangoSearch("potatoes");
ArangoSearchPropertiesEntity properties = view.getProperties(); ArangoSearchPropertiesEntity properties = view.getProperties();
``` ```

View File

@ -23,7 +23,7 @@ Checks whether the view exists
```Java ```Java
ArangoDB arango = new ArangoDB.Builder().build(); ArangoDB arango = new ArangoDB.Builder().build();
ArangoDatabase db = arango.db("myDB"); ArangoDatabase db = arango.db("myDB");
ArangoView view = db.view("potatos"); ArangoView view = db.view("potatoes");
boolean exists = view.exists(); boolean exists = view.exists();
``` ```
@ -41,7 +41,7 @@ Returns information about the view.
```Java ```Java
ArangoDB arango = new ArangoDB.Builder().build(); ArangoDB arango = new ArangoDB.Builder().build();
ArangoDatabase db = arango.db("myDB"); ArangoDatabase db = arango.db("myDB");
ArangoView view = db.view("potatos"); ArangoView view = db.view("potatoes");
ViewEntity info = view.getInfo(); ViewEntity info = view.getInfo();
``` ```

View File

@ -28,7 +28,7 @@ Creates a view of the given _type_, then returns view information from the serve
ArangoDB arango = new ArangoDB.Builder().build(); ArangoDB arango = new ArangoDB.Builder().build();
ArangoDatabase db = arango.db("myDB"); ArangoDatabase db = arango.db("myDB");
db.createView("myView", ViewType.ARANGO_SEARCH); db.createView("myView", ViewType.ARANGO_SEARCH);
// the view "potatos" now exists // the view "potatoes" now exists
``` ```
## ArangoView.rename ## ArangoView.rename

View File

@ -20,7 +20,7 @@ opaque strings when they store or use it locally.
Collection Name Collection Name
--------------- ---------------
A collection name identifies a collection in a database. It is a string and is unique within the database. Unlike the collection identifier it is supplied by the creator of the collection. The collection name must consist of letters, digits, and the _ (underscore) and - (dash) characters only. Please refer to [NamingConventions](../DataModeling/NamingConventions/CollectionNames.md) for more information on valid collection names. A collection name identifies a collection in a database. It is a string and is unique within the database. Unlike the collection identifier it is supplied by the creator of the collection. The collection name must consist of letters, digits, and the _ (underscore) and - (dash) characters only. Please refer to [NamingConventions](../DataModeling/NamingConventions/CollectionAndViewNames.md) for more information on valid collection names.
Database Database
-------- --------
@ -222,7 +222,7 @@ renamed. Renaming a view will change the view name, but not the view identifier.
The conceptual transformation function employed by a view type is implementation The conceptual transformation function employed by a view type is implementation
specific. The type is specified by the user when the view is created, and cannot specific. The type is specified by the user when the view is created, and cannot
be changed later. The following view types are currently supported: be changed later. The following view types are currently supported:
* [arangosearch](../Views/ArangoSearch/README.md) * [`arangosearch`](../Views/ArangoSearch/README.md)
View Identifier View Identifier
--------------- ---------------
@ -244,7 +244,7 @@ A view name identifies a view in a database. It is a string and is unique within
the database. Unlike the view identifier it is supplied by the creator of the the database. Unlike the view identifier it is supplied by the creator of the
view. The view name must consist of letters, digits, and the _ (underscore) view. The view name must consist of letters, digits, and the _ (underscore)
and - (dash) characters only. Please refer to and - (dash) characters only. Please refer to
[NamingConventions](../DataModeling/NamingConventions/CollectionNames.md) for [Naming Conventions](../DataModeling/NamingConventions/CollectionAndViewNames.md) for
more information on valid view names, which follow the same guidelines as more information on valid view names, which follow the same guidelines as
collection names. collection names.

View File

@ -11,11 +11,14 @@ Address of a Collection
----------------------- -----------------------
All collections in ArangoDB have a unique identifier and a unique All collections in ArangoDB have a unique identifier and a unique
name. ArangoDB internally uses the collection's unique identifier to look up name. The namespace for collections is shared with views, so there cannot exist
collections. This identifier, however, is managed by ArangoDB and the user has a collection and a view with the same name in the same database. ArangoDB
no control over it. In order to allow users to use their own names, each collection internally uses the collection's unique identifier to look up collections. This
also has a unique name which is specified by the user. To access a collection identifier, however, is managed by ArangoDB and the user has no control over it.
from the user perspective, the [collection name](../../Appendix/Glossary.md#collection-name) should be used, i.e.: In order to allow users to use their own names, each collection also has a
unique name which is specified by the user. To access a collection from the user
perspective, the [collection name](../../Appendix/Glossary.md#collection-name)
should be used, i.e.:
### Collection ### Collection
`db._collection(collection-name)` `db._collection(collection-name)`

View File

@ -1,8 +1,8 @@
Collection Names Collection and View Names
================ =========================
Users can pick names for their collections as desired, provided the following Users can pick names for their collections (or views) as desired, provided the
naming constraints are not violated: following naming constraints are not violated:
* Collection names must only consist of the letters *a* to *z* (both in lower * Collection names must only consist of the letters *a* to *z* (both in lower
and upper case), the numbers *0* to *9*, and the underscore (*_*) or dash (*-*) and upper case), the numbers *0* to *9*, and the underscore (*_*) or dash (*-*)
@ -14,4 +14,3 @@ naming constraints are not violated:
should not be used by end users for their own collections should not be used by end users for their own collections
* The maximum allowed length of a collection name is 64 bytes * The maximum allowed length of a collection name is 64 bytes
* Collection names are case-sensitive * Collection names are case-sensitive

View File

@ -10,6 +10,16 @@ View
Returns the view with the given name or null if no such view exists. Returns the view with the given name or null if no such view exists.
@startDocuBlockInline viewDatabaseGet
@EXAMPLE_ARANGOSH_OUTPUT{viewDatabaseGet}
~ db._createView("example", "arangosearch", {});
| view = db._view("example");
// or, alternatively
view = db["example"]
~ db._dropView("example");
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewDatabaseGet
`db._view(view-identifier)` `db._view(view-identifier)`
Returns the view with the given identifier or null if no such view exists. Returns the view with the given identifier or null if no such view exists.
@ -23,17 +33,10 @@ Get a view by name:
@startDocuBlockInline viewDatabaseNameKnown @startDocuBlockInline viewDatabaseNameKnown
@EXAMPLE_ARANGOSH_OUTPUT{viewDatabaseNameKnown} @EXAMPLE_ARANGOSH_OUTPUT{viewDatabaseNameKnown}
db._view("demo"); db._view("demoView");
@END_EXAMPLE_ARANGOSH_OUTPUT @END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewDatabaseNameKnown @endDocuBlock viewDatabaseNameKnown
Get a view by id:
```
arangosh> db._view(123456);
[ArangoView 123456, "demo"]
```
Unknown view: Unknown view:
@startDocuBlockInline viewDatabaseNameUnknown @startDocuBlockInline viewDatabaseNameUnknown
@ -50,24 +53,33 @@ Create
`db._createView(view-name, view-type, view-properties)` `db._createView(view-name, view-type, view-properties)`
*view-type* must be one of the supported [View Types](README.md)
*view-properties* view configuration specific to each view-type
Creates a new view named *view-name* of type *view-type* with properties Creates a new view named *view-name* of type *view-type* with properties
*view-properties*. If the view name already exists or if the name format is *view-properties*.
invalid, an error is thrown. For more information on valid view names please
refer to the [naming conventions](../NamingConventions/README.md). *view-name* is a string and the name of the view. No view or collection with the
same name may already exist in the current database. For more information on
valid view names please refer to the [naming conventions
](../NamingConventions/README.md).
*view-type* must be the string `"arangosearch"`, as it is currently the only
supported view type.
*view-properties* is an optional object containing view configuration specific
to each view-type. Currently, only ArangoSearch Views are supported. See
[ArangoSearch View definition
](../../Views/ArangoSearch/DetailedOverview.md#view-definitionmodification) for
details.
**Examples** **Examples**
Create a view: @startDocuBlockInline viewDatabaseCreate
@EXAMPLE_ARANGOSH_OUTPUT{viewDatabaseCreate}
v = db._createView("example", "arangosearch");
v.properties()
db._dropView("example")
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewDatabaseCreate
```
arangosh> v = db._createView("example", \<view-type\>, \<view-properties\>);
arangosh> v.properties();
arangosh> db._dropView("example");
```
All Views All Views
--------- ---------
@ -81,13 +93,15 @@ Returns all views of the given database.
**Examples** **Examples**
Query views: List all views:
``` @startDocuBlockInline viewDatabaseList
arangosh> db._createView("example", \<view-type\>, \<view-properties\>); @EXAMPLE_ARANGOSH_OUTPUT{viewDatabaseList}
arangosh> db._views(); ~ db._createView("exampleView", "arangosearch");
arangosh> db._dropView("example"); db._views();
``` ~ db._dropView("exampleView");
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewDatabaseList
Drop Drop
---- ----
@ -108,9 +122,10 @@ thrown if there is no such view.
Drop a view: Drop a view:
``` @startDocuBlockInline viewDatabaseDrop
arangosh> db._createView("example", \<view-type\>, \<view-properties\>); @EXAMPLE_ARANGOSH_OUTPUT{viewDatabaseDrop}
arangosh> v = db._view("example"); db._createView("exampleView", "arangosearch");
arangosh> db._dropView("example"); db._dropView("exampleView");
arangosh> v; db._view("exampleView");
``` @END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewDatabaseDrop

View File

@ -2,42 +2,97 @@ JavaScript Interface to Views
============================= =============================
This is an introduction to ArangoDB's interface for views and how to handle This is an introduction to ArangoDB's interface for views and how to handle
views fron the JavaScript shell _arangosh_. For other languages see the views from the JavaScript shell _arangosh_. For other languages see the
corresponding language API. corresponding language API.
Address of a View Address of a View
----------------- -----------------
All views in ArangoDB have a unique identifier and a unique name. Like [collections](../Collections/README.md), views are accessed by the user via
ArangoDB internally uses their unique name and internally via their identifier. Using the identifier for
the view's unique identifier to look up views. This identifier, however, is accessing views is discouraged. Views share their namespace with collections,
managed by ArangoDB and the user has no control over it. In order to allow users so there cannot exist a view and a collection with the same name in the same
to use their own names, each view also has a unique name which is specified by database.
the user. To access a view from the user perspective, the
[view name](../../Appendix/Glossary.md#view-name) should be used, i.e.:
### View Usage
`db._view(view-name)` -----
A view is created by a ["db._createView"](DatabaseMethods.md) call. The returned Here follow some basic usage examples. More details can be found in the
object may then be used via the [exposed methods](ViewMethods.md). following chapters:
- [Database Methods for Views](DatabaseMethods.md)
- [View Methods](ViewMethods.md)
- [ArangoSearch Views](../Views/README.md)
For example: Assume that the Create a view with default properties:
[view identifier](../../Appendix/Glossary.md#view-identifier) is *7254820* and
the name is *demo*, then the view can be accessed as:
db._view("demo") @startDocuBlockInline viewUsage_01
@EXAMPLE_ARANGOSH_OUTPUT{viewUsage_01}
~ db._create("colA");
~ db._create("colB");
view = db._createView("myView", "arangosearch", {});
~ addIgnoreCollection("colA");
~ addIgnoreCollection("colB");
~ addIgnoreView("myView");
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewUsage_01
If no view with such a name exists, then *null* is returned. Get this view again later by name:
### Create @startDocuBlockInline viewUsage_02
`db._createView(view-name, view-type, view-properties)` @EXAMPLE_ARANGOSH_OUTPUT{viewUsage_02}
view = db._view("myView");
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewUsage_02
This call will create a new view called *view-name*. This method is a database Get the view properties:
method and is documented in detail in
[Database Methods](DatabaseMethods.md#create)
### View Types @startDocuBlockInline viewUsage_03
@EXAMPLE_ARANGOSH_OUTPUT{viewUsage_03}
view.properties();
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewUsage_03
The currently supported view implementation is: **arangosearch** as described in Set a view property:
[ArangoSearch View](../../Views/ArangoSearch/README.md).
@startDocuBlockInline viewUsage_04
@EXAMPLE_ARANGOSH_OUTPUT{viewUsage_04}
view.properties({cleanupIntervalStep: 12});
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewUsage_04
Add a link:
@startDocuBlockInline viewUsage_05
@EXAMPLE_ARANGOSH_OUTPUT{viewUsage_05}
view.properties({links: {colA: {includeAllFields: true}}});
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewUsage_05
Add another link:
@startDocuBlockInline viewUsage_06
@EXAMPLE_ARANGOSH_OUTPUT{viewUsage_06}
view.properties({links: {colB: {fields: {text: {}}}}});
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewUsage_06
Remove the first link again:
@startDocuBlockInline viewUsage_07
@EXAMPLE_ARANGOSH_OUTPUT{viewUsage_07}
view.properties({links: {colA: null}});
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewUsage_07
Drop the view:
@startDocuBlockInline viewUsage_08
@EXAMPLE_ARANGOSH_OUTPUT{viewUsage_08}
~ removeIgnoreCollection("colA");
~ removeIgnoreCollection("colB");
~ removeIgnoreView("myView");
db._dropView("myView");
~ db._drop("colA");
~ db._drop("colB");
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewUsage_08

View File

@ -12,15 +12,17 @@ Drops a *view* and all its data.
**Examples** **Examples**
Drop a view: Drop a view:
``` @startDocuBlockInline viewDrop
arangosh> db._createView("example", \<view-type\>, \<view-properties\>); @EXAMPLE_ARANGOSH_OUTPUT{viewDrop}
arangosh> v = db._view("example"); | v = db._createView("example", "arangosearch");
arangosh> v.drop(); // or
arangosh> v; v = db._view("example");
``` v.drop();
db._view("example");
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewDrop
Query Name Query Name
---------- ----------
@ -35,37 +37,40 @@ Returns the name of the *view*.
Get view name: Get view name:
``` @startDocuBlockInline viewName
arangosh> db._createView("example", \<view-type\>, \<view-properties\>); @EXAMPLE_ARANGOSH_OUTPUT{viewName}
arangosh> v = db._view("example"); v = db._view("demoView");
arangosh> v.name(); v.name();
arangosh> db._dropView("example"); @END_EXAMPLE_ARANGOSH_OUTPUT
``` @endDocuBlock viewName
Modify Name Rename
----------- ------
<!-- arangod/V8Server/v8-views.cpp --> <!-- arangod/V8Server/v8-views.cpp -->
`view.rename(new-name)` `view.rename(new-name)`
Renames a view using the *new-name*. The *new-name* must not already be used by Renames a view using the *new-name*. The *new-name* must not already be used by
a different view. *new-name* must also be a valid view name. For a different view or collection in the same database. *new-name* must also be a
more information on valid view names please refer to the valid view name. For more information on valid view names please refer to the
[naming conventions](../NamingConventions/README.md). [naming conventions](../NamingConventions/README.md).
If renaming fails for any reason, an error is thrown. If renaming fails for any reason, an error is thrown.
**Note**: this method is not available in a cluster.
**Examples** **Examples**
``` @startDocuBlockInline viewRename
arangosh> db._createView("example", \<view-type\>, \<view-properties\>); @EXAMPLE_ARANGOSH_OUTPUT{viewRename}
arangosh> v = db._view("example"); v = db._createView("example", "arangosearch");
arangosh> v.name(); v.name();
arangosh> v.rename("example-renamed"); v.rename("exampleRenamed");
arangosh> v.name(); v.name();
arangosh> db._dropView("example-renamed"); ~ db._dropView("exampleRenamed");
``` @END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewRename
Query Type Query Type
---------- ----------
@ -80,12 +85,12 @@ Returns the type of the *view*.
Get view type: Get view type:
``` @startDocuBlockInline viewType
arangosh> db._createView("example", \<view-type\>, \<view-properties\>); @EXAMPLE_ARANGOSH_OUTPUT{viewType}
arangosh> v = db._view("example"); v = db._view("demoView");
arangosh> v.type(); v.type();
arangosh> db._dropView("example"); @END_EXAMPLE_ARANGOSH_OUTPUT
``` @endDocuBlock viewType
Query Properties Query Properties
---------------- ----------------
@ -101,30 +106,46 @@ each of the supported [View Types](README.md).
Get view properties: Get view properties:
``` @startDocuBlockInline viewGetProperties
arangosh> db._createView("example", \<view-type\>, \<view-properties\>); @EXAMPLE_ARANGOSH_OUTPUT{viewGetProperties}
arangosh> v = db._view("example"); v = db._view("demoView");
arangosh> v.properties(); v.properties();
arangosh> db._dropView("example"); @END_EXAMPLE_ARANGOSH_OUTPUT
``` @endDocuBlock viewGetProperties
Modify Properties Modify Properties
----------------- -----------------
<!-- arangod/V8Server/v8-views.cpp --> <!-- arangod/V8Server/v8-views.cpp -->
`view.properties(view-property-modification)` `view.properties(view-property-modification, partialUpdate)`
Modifies the properties of the *view*. The format of the result is specific to Modifies the properties of the *view*. The format of the result is specific to
each of the supported [View Types](README.md). each of the supported [View Types](README.md). *partialUpdate* is an optional
boolean parameter (`true` by default) that determines how
*view-property-modification* is merged with current view *properties* (adds or
updates *view-property-modification* properties to current if `true` and,
additionally, removes all other properties if `false`).
Currently, the only supported view type is `arangosearch`, and its properties
can be found in
[](../../Views/ArangoSearch/DetailedOverview.md#view-properties).
**Examples** **Examples**
Modify view properties: Modify view properties:
``` @startDocuBlockInline viewModifyProperties
arangosh> db._createView("example", \<view-type\>, \<view-properties\>); @EXAMPLE_ARANGOSH_OUTPUT{viewModifyProperties}
arangosh> v = db._view("example"); ~ db._createView("example", "arangosearch");
arangosh> v.properties(\<view-property-modification\>); v = db._view("example");
arangosh> db._dropView("example"); | v.properties();
``` // set cleanupIntervalStep to 12
| v.properties({cleanupIntervalStep: 12});
// add a link
| v.properties({links: {demo: {}}})
// remove a link
v.properties({links: {demo: null}})
~ db._dropView("example");
@END_EXAMPLE_ARANGOSH_OUTPUT
@endDocuBlock viewModifyProperties

View File

@ -91,7 +91,7 @@
* [View Methods](DataModeling/Views/ViewMethods.md) * [View Methods](DataModeling/Views/ViewMethods.md)
* [Naming Conventions](DataModeling/NamingConventions/README.md) * [Naming Conventions](DataModeling/NamingConventions/README.md)
* [Database Names](DataModeling/NamingConventions/DatabaseNames.md) * [Database Names](DataModeling/NamingConventions/DatabaseNames.md)
* [Collection Names](DataModeling/NamingConventions/CollectionNames.md) * [Collection and View Names](DataModeling/NamingConventions/CollectionAndViewNames.md)
* [Document Keys](DataModeling/NamingConventions/DocumentKeys.md) * [Document Keys](DataModeling/NamingConventions/DocumentKeys.md)
* [Attribute Names](DataModeling/NamingConventions/AttributeNames.md) * [Attribute Names](DataModeling/NamingConventions/AttributeNames.md)
* [Indexing](Indexing/README.md) * [Indexing](Indexing/README.md)

View File

@ -1,111 +1,57 @@
ArangoSearch Analyzers ArangoSearch Analyzers
====================== ======================
To simplify query syntax ArangoSearch provides a concept of named analyzers which To simplify query syntax ArangoSearch provides a concept of named analyzers
are merely aliases for type+configuration of IResearch analyzers. Management of which are merely aliases for type+configuration of IResearch analyzers. In the
named analyzers will be exposed in upcoming ArangoDB versions via REST, GUI future, users will be able to specify their own named analyzers. For now,
and JavaScript APIs, e.g. ArangoDB comes with the following analyzers:
`db._globalSettings("iresearch.analyzers")`
A user then merely uses these analyzer names in ArangoSearch view configurations
and AQL queries.
ArangoSearch provides a 'text' analyzer to analyze human readable text. A required
configuration parameter for this type of analyzer is 'locale' used to specify
the language used for analysis.
The ArangoDB administrator may then set up a named analyzer 'text_des':
```json
{
"name": "text_des",
"type": "text",
"properties": {
"locale": "de-ch"
}
}
```
The user is then immediately able to run queries with the said analyzer, e.g.
`SEARCH doc.description IN TOKENS('Ein brauner Fuchs springt', 'text_des')`
Similarly an administrator may choose to deploy a custom DNA analyzer 'DnaSeq':
```json
{
"name": "dna",
"type": "DnaSeq",
"properties": "use-human-config"
}
```
The user is then immediately able to run queries with the said analyzer, e.g.
`SEARCH doc.dna IN TOKENS('ACGTCGTATGCACTGA', 'DnaSeq')`
To a limited degree the concept of 'analysis' is even available in non-IResearch
AQL, e.g. the `TOKENS(...)` function will utilize the power of IResearch to break
up a value into an AQL array that can be used anywhere in the AQL query.
In plain terms this means a user can match a document attribute when its
value matches at least one value form a set, (yes this is independent of doc),
e.g. to match docs with 'word == quick' OR 'word == brown' OR 'word == fox'
FOR doc IN someCollection
FILTER doc.word IN TOKENS('a quick brown fox', 'text_en')
RETURN doc
Runtime-plugging functionality for analyzers is not available in ArangoDB at
this point in time, so ArangoDB comes with a few default-initialized analyzers:
* `identity` * `identity`
treat the value as an atom treat the value as an atom
* `text_de` * `text_de`
tokenize the value into case-insensitive word stems as per the German locale, tokenize the value into case-insensitive word stems as per the German locale,
do not discard any any stopwords do not discard any stopwords
* `text_en` * `text_en`
tokenize the value into case-insensitive word stems as per the English locale, tokenize the value into case-insensitive word stems as per the English locale,
do not discard any any stopwords do not discard any stopwords
* `text_es` * `text_es`
tokenize the value into case-insensitive word stems as per the Spanish locale, tokenize the value into case-insensitive word stems as per the Spanish locale,
do not discard any any stopwords do not discard any stopwords
* `text_fi` * `text_fi`
tokenize the value into case-insensitive word stems as per the Finnish locale, tokenize the value into case-insensitive word stems as per the Finnish locale,
do not discard any any stopwords do not discard any stopwords
* `text_fr` * `text_fr`
tokenize the value into case-insensitive word stems as per the French locale, tokenize the value into case-insensitive word stems as per the French locale,
do not discard any any stopwords do not discard any stopwords
* `text_it` * `text_it`
tokenize the value into case-insensitive word stems as per the Italian locale, tokenize the value into case-insensitive word stems as per the Italian locale,
do not discard any any stopwords do not discard any stopwords
* `text_nl` * `text_nl`
tokenize the value into case-insensitive word stems as per the Dutch locale, tokenize the value into case-insensitive word stems as per the Dutch locale,
do not discard any any stopwords do not discard any stopwords
* `text_no` * `text_no`
tokenize the value into case-insensitive word stems as per the Norwegian tokenize the value into case-insensitive word stems as per the Norwegian
locale, do not discard any any stopwords locale, do not discard any stopwords
* `text_pt` * `text_pt`
tokenize the value into case-insensitive word stems as per the Portuguese tokenize the value into case-insensitive word stems as per the Portuguese
locale, do not discard any any stopwords locale, do not discard any stopwords
* `text_ru` * `text_ru`
tokenize the value into case-insensitive word stems as per the Russian locale, tokenize the value into case-insensitive word stems as per the Russian locale,
do not discard any any stopwords do not discard any stopwords
* `text_sv` * `text_sv`
tokenize the value into case-insensitive word stems as per the Swedish locale, tokenize the value into case-insensitive word stems as per the Swedish locale,
do not discard any any stopwords do not discard any stopwords
* `text_zh` * `text_zh`
tokenize the value into word stems as per the Chinese locale tokenize the value into word stems as per the Chinese locale

View File

@ -1,18 +1,18 @@
# Detailed overview of ArangoSearch views # Detailed overview of ArangoSearch Views
ArangoSearch is a powerful fulltext search component with additional functionality, ArangoSearch is a powerful fulltext search component with additional
supported via the 'text' analyzer and 'tfidf'/'bm25' [scorers](Scorers.md), functionality, supported via the 'text' analyzer and 'tfidf'/'bm25'
without impact on performance when specifying documents from different collections or [scorers](Scorers.md), without impact on performance when specifying documents
filtering on multiple document attributes. from different collections or filtering on multiple document attributes.
## View datasource ## View datasource
Search functionality is exposed to ArangoDB via the view API for views Search functionality is exposed to ArangoDB via the view API for views of type
of type *arangosearch*. The ArangoSearch view is merely an identity `arangosearch`. The ArangoSearch View is merely an identity transformation
transformation applied onto documents stored in linked collections of the same ArangoDB database. applied onto documents stored in linked collections of the same ArangoDB
In plain terms an ArangoSearch view only allows filtering and sorting of documents database. In plain terms an ArangoSearch View only allows filtering and sorting
located in collections of the same database. The matching documents themselves of documents located in collections of the same database. The matching documents
are returned as-is from their corresponding collections. themselves are returned as-is from their corresponding collections.
## Links to ArangoDB collections ## Links to ArangoDB collections
@ -21,48 +21,45 @@ which ArangoDB collections a given ArangoSearch View should query for documents
and how these documents should be queried. and how these documents should be queried.
An ArangoSearch Link is a uni-directional connection from an ArangoDB collection An ArangoSearch Link is a uni-directional connection from an ArangoDB collection
to an ArangoSearch view describing how data coming from the said collection should to an ArangoSearch View describing how data coming from the said collection
be made available in the given view. Each ArangoSearch Link in an ArangoSearch should be made available in the given view. Each ArangoSearch Link in an
view is uniquely identified by the name of the ArangoDB collection it links to. ArangoSearch view is uniquely identified by the name of the ArangoDB collection
An ArangoSearch view may have zero or more links, each to a distinct ArangoDB it links to. An ArangoSearch View may have zero or more links, each to a
collection. Similarly an ArangoDB collection may be referenced via links by zero distinct ArangoDB collection. Similarly an ArangoDB collection may be referenced
or more distinct ArangoSearch views. In plain terms any given ArangoSearch view via links by zero or more distinct ArangoSearch Views. In other words, any given
may be linked to any given ArangoDB collection of the same database with zero or ArangoSearch View may be linked to any given ArangoDB collection of the same
at most one link. However, any ArangoSearch view may be linked to multiple database with zero or one link. However, any ArangoSearch View may be linked to
distinct ArangoDB collections and similarly any ArangoDB collection may be multiple distinct ArangoDB collections and similarly any ArangoDB collection may
referenced by multiple ArangoSearch views. be referenced by multiple ArangoSearch Views.
To configure an ArangoSearch view for consideration of documents from a given To configure an ArangoSearch View for consideration of documents from a given
ArangoDB collection a link definition must be added to the properties of the ArangoDB collection a link definition must be added to the properties of the
said ArangoSearch view defining the link parameters as per the section said ArangoSearch View defining the link parameters as per the section
[View definition/modification](#view-definitionmodification). [View definition/modification](#view-definitionmodification).
## Index ## Index
Inverted Index is the heart of ArangoSearch. The index consists of several Inverted Index is the heart of ArangoSearch. The index consists of several
independent segments and the index segment itself is meant to be treated as independent segments and the index segment itself is meant to be treated as a
a standalone index. standalone index.
## Analyzers ## Analyzers
To simplify query syntax ArangoSearch provides a concept of To simplify query syntax ArangoSearch provides a concept of [named
[named analyzers](Analyzers.md) which are merely aliases for analyzers](Analyzers.md) which are merely aliases for type+configuration of
type+configuration of IResearch analyzers. Management of named analyzers IResearch analyzers. <!-- Management of named analyzers is exposed via REST, GUI and
is exposed via REST, GUI and JavaScript APIs. JavaScript APIs. -->
## View definition/modification ## View definition/modification
An ArangoSearch view is configured via an object containing a set of An ArangoSearch View is configured via an object containing a set of
view-specific configuration directives and a map of link-specific configuration view-specific configuration directives and a map of link-specific configuration
directives. directives.
During view creation the following directives apply: During view creation the following directives apply:
* **id** (_optional_; type: `string`): the desired view identifier
* **name** (_required_; type: `string`): the view name * **name** (_required_; type: `string`): the view name
* **type** (_required_; type: `string`): the value "arangosearch"<br/> * **type** (_required_; type: `string`): the value `"arangosearch"`
* any of the directives from the section [View properties](#view-properties) * any of the directives from the section [View properties](#view-properties)
During view modification the following directives apply: During view modification the following directives apply:
@ -75,118 +72,139 @@ During view modification the following directives apply:
## View properties ## View properties
The following terminology from ArangoSearch architecture is used to understand The following terminology from ArangoSearch architecture is used to understand
view properties assignment of its type:<br/> view properties assignment of its type:
The index consists of several independent segments and the index **segment** itself
is meant to be treated as a standalone index. **Commit** is meant to be treated The index consists of several independent segments and the index **segment**
as the procedure of accumulating processed data itself is meant to be treated as a standalone index. **Commit** is meant to be
creating new index segments. **Consolidation** is meant to be treated as the procedure treated as the procedure of accumulating processed data creating new index
of joining multiple index segments into a bigger one and removing garbage documents segments. **Consolidation** is meant to be treated as the procedure of joining
(e.g. deleted from a collection). **Cleanup** is meant to be treated as the multiple index segments into a bigger one and removing garbage documents (e.g.
procedure of removing unused segments after release of internal resources. deleted from a collection). **Cleanup** is meant to be treated as the procedure
of removing unused segments after release of internal resources.
* **cleanupIntervalStep** (_optional_; type: `integer`; default: `10`; to
disable use: `0`)
* **cleanupIntervalStep** (_optional_; type: `integer`; default: `10`; to disable use: `0`)<br/>
ArangoSearch waits at least this many commits between removing unused files in ArangoSearch waits at least this many commits between removing unused files in
its data directory its data directory for the case where the consolidation policies merge
for the case where the consolidation policies merge segments often (i.e. a segments often (i.e. a lot of commit+consolidate). A lower value will cause a
lot of commit+consolidate). A lower value will cause a lot of disk space to lot of disk space to be wasted for the case where the consolidation policies
be wasted rarely merge segments (i.e. few inserts/deletes). A higher value will impact
for the case where the consolidation policies rarely merge segments (i.e. performance without any added benefits.
few inserts/deletes). A higher value will impact performance without any
added benefits.
>With every "commit" or "consolidate" operation a new state of the view
internal data-structures is created on disk old states/snapshots are released once there are no longer any users
remaining however, the files for the released states/snapshots are left on disk, and
only removed by "cleanup" operation.
* **consoloidationIntervalMsec** (_optional_; type: `integer`; default: `60000`; to disable use: `0`)<br/> > With every **commit** or **consolidate** operation a new state of the view
ArangoSearch waits at least this many milliseconds between committing view data store > internal data-structures is created on disk. Old states/snapshots are
changes and making documents visible to queries > released once there are no longer any users remaining. However, the files
for the case where there are a lot of inserts/updates. A lower value will > for the released states/snapshots are left on disk, and only removed by
cause the view not to account for them, (until commit), and memory usage > "cleanup" operation.
would continue to grow
for the case where there are a few inserts/updates. A higher value will
impact performance and waste disk space for each commit call without any
added benefits.
>For data retrieval ArangoSearch views follow the concept of
"eventually-consistent", i.e. eventually all the data in ArangoDB will be
matched by corresponding query expressions
the concept of ArangoSearch view "commit" operation is introduced to
control the upper-bound on the time until document addition/removals are
actually reflected by corresponding query expressions
once a "commit" operation is complete all documents added/removed prior to
the start of the "commit" operation will be reflected by queries invoked in
subsequent ArangoDB transactions, in-progress ArangoDB transactions will
still continue to return a repeatable-read state.
* **consolidationPolicy** (_optional_; type: `object`; default: `{}`)<br/> * **consolidationIntervalMsec** (_optional_; type: `integer`; default: `60000`;
the consolidation policy to apply for selecting data store segment merge to disable use: `0`)
ArangoSearch waits _at least_ this many milliseconds between committing view
data store changes and making documents visible to queries. A lower value
will cause the view not to account for them, (until commit), and memory usage
would continue to grow for the case where there are a few inserts/updates. A
higher value will impact performance and waste disk space for each commit call
without any added benefits.
> For data retrieval ArangoSearch Views follow the concept of
> "eventually-consistent", i.e. eventually all the data in ArangoDB will be
> matched by corresponding query expressions. The concept of an ArangoSearch
> View "commit" operation is introduced to control the upper-bound on the time
> until document addition/removals are actually reflected by corresponding
> query expressions. Once a **commit** operation is complete, all documents
> added/removed prior to the start of the **commit** operation will be
> reflected by queries invoked in subsequent ArangoDB transactions, while
> in-progress ArangoDB transactions will still continue to return a
> repeatable-read state.
* **consolidationPolicy** (_optional_; type: `object`; default: `{}`)
The consolidation policy to apply for selecting data store segment merge
candidates. candidates.
>With each ArangoDB transaction that inserts documents one or more
ArangoSearch internal segments gets created
similarly for removed documents the segments that contain such documents
will have these documents marked as 'deleted'
over time this approach causes a lot of small and sparse segments to be
created
a "consolidation" operation selects one or more segments and copies all of
their valid documents into a single new segment, thereby allowing the
search algorithm to perform more optimally and for extra file handles to be
released once old segments are no longer used.
* **type** (_optional_; type: `string`; default: `"bytes_accum"`)<br/> > With each ArangoDB transaction that inserts documents, one or more
the segment candidates for the "consolidation" operation are selected based > ArangoSearch internal segments gets created. Similarly, for removed
upon several possible configurable formulas as defined by their types > documents the segments containing such documents will have these documents
the currently supported types are: > marked as "deleted". Over time this approach causes a lot of small and
- **bytes**: consolidate if and only if > sparse segments to be created. A **consolidation** operation selects one or
`{threshold} > segment_bytes / (all_segment_bytes / number_of_segments)` > more segments and copies all of their valid documents into a single new
i.e. the candidate segment byte size is less that the average segment byte size multiplied by the `{threshold}` > segment, thereby allowing the search algorithm to perform more optimally and
- **bytes_accum**: consolidate if and only if > for extra file handles to be released once old segments are no longer used.
`{threshold} > (segment_bytes + sum_of_merge_candidate_segment_bytes) / all_segment_bytes`
i.e. the sum of all candidate segment byte size is less than the total segment byte size multiplied by the `{threshold}`
- **count**: consolidate if and only if
`{threshold} > segment_docs{valid} / (all_segment_docs{valid} / number_of_segments)`
i.e. the candidate segment non-deleted document count is less that the average segment non-deleted document count size multiplied by the `{threshold}`
- **fill**: consolidate if and only if:
`{threshold} > #segment_docs{valid} / (#segment_docs{valid} + number_of_segment_docs{removed})`
i.e. the candidate segment valid document count is less that the average segment total document count multiplied by the `{threshold}`
* **segmentThreshold** (_optional_; type: `integer`; default: `300`)<br/> * **type** (_optional_; type: `string`; default: `"bytes_accum"`)
apply the "consolidation" operation if and only if `{segmentThreshold} < number_of_segments`
* **threshold** (_optional_; type: `float`; default: `0.85`)<br/> The segment candidates for the "consolidation" operation are selected based
select a given segment for "consolidation" if and only if the formula based upon several possible configurable formulas as defined by their types.
on *type* (as defined above) evaluates to true, valid value range The currently supported types are:
`[0.0, 1.0]`
- **bytes**: Consolidate if and only if `{threshold} > segment_bytes /
(all_segment_bytes / number_of_segments)`, i.e. the candidate segment's
byte size is less than the average segment's byte size multiplied by the
`{threshold}`.
- **bytes_accum**: Consolidate if and only if `{threshold} > (segment_bytes
+ sum_of_merge_candidate_segment_bytes) / all_segment_bytes`, i.e. the sum
of all candidate segment's byte size is less than the total segment byte
size multiplied by the `{threshold}`.
- **count**: Consolidate if and only if `{threshold} > segment_docs{valid} /
(all_segment_docs{valid} / number_of_segments)`, i.e. the candidate
segment's non-deleted document count is less than the average segment's
non-deleted document count size multiplied by the `{threshold}`.
- **fill**: Consolidate if and only if `{threshold} > #segment_docs{valid} /
(#segment_docs{valid} + number_of_segment_docs{removed})`, i.e. the
candidate segment's valid document count is less than the average
segment's total document count multiplied by the `{threshold}`.
* **segmentThreshold** (_optional_; type: `integer`; default: `300`)
Apply the "consolidation" operation if and only if `{segmentThreshold} <
number_of_segments`.
* **threshold** (_optional_; type: `float`; default: `0.85`)
Select a given segment for **consolidation** if and only if the formula
based on *type* (as defined above) evaluates to true. Valid values are in
the range `[0.0, 1.0]`.
## Link properties ## Link properties
* **analyzers** (_optional_; type: `array`; subtype: `string`; default: `[ 'identity' ]`)<br/> * **analyzers** (_optional_; type: `array`; subtype: `string`; default: `[
a list of analyzers, by name as defined via the [Analyzers](Analyzers.md), that 'identity' ]`)
should be applied to values of processed document attributes
* **fields** (_optional_; type: `object`; default: `{}`)<br/> A list of analyzers, by name as defined via the [Analyzers](Analyzers.md),
an object `{attribute-name: [Link properties]}` of fields that should be that should be applied to values of processed document attributes.
processed at each level of the document
each key specifies the document attribute to be processed, the value of
*includeAllFields* is also consulted when selecting fields to be processed
each value specifies the [Link properties](#link-properties) directives to be used when
processing the specified field, a Link properties value of `{}` denotes
inheritance of all (except *fields*) directives from the current level
* **includeAllFields** (_optional_; type: `boolean`; default: `false`)<br/> * **fields** (_optional_; type: `object`; default: `{}`)
if true then process all document attributes (if not explicitly specified
then process the fields with default Link properties directives, i.e. `{}`),
otherwise only consider attributes mentioned in *fields*
* **trackListPositions** (_optional_; type: `boolean`; default: `false`)<br/> An object `{attribute-name: [Link properties]}` of fields that should be
if true then for array values track the value position in the array, e.g. when processed at each level of the document. Each key specifies the document
querying for the input: `{ attr: [ 'valueX', 'valueY', 'valueZ' ] }` attribute to be processed. Note that the value of `includeAllFields` is also
the user must specify: `doc.attr[1] == 'valueY'` consulted when selecting fields to be processed. Each value specifies the
otherwise all values in an array are treated as equal alternatives, e.g. when [Link properties](#link-properties) directives to be used when processing the
querying for the input: `{ attr: [ 'valueX', 'valueY', 'valueZ' ] }` specified field, a Link properties value of `{}` denotes inheritance of all
the user must specify: `doc.attr == 'valueY'` (except `fields`) directives from the current level.
* **storeValues** (_optional_; type: `string`; default: `"none"`)<br/> * **includeAllFields** (_optional_; type: `boolean`; default: `false`)
how should the view track the attribute values, this setting allows for
additional value retrieval optimizations, one of: If set to `true`, then process all document attributes. Otherwise, only
* **none**: Do not store values by the view consider attributes mentioned in `fields`. Attributes not explicitly
* **id**: Store only information about value presence, to allow use of the `EXISTS()` function specified in `fields` will be processed with default link properties, i.e.
`{}`.
* **trackListPositions** (_optional_; type: `boolean`; default: `false`)
If set to `true`, then for array values track the value position in arrays.
E.g., when querying for the input `{ attr: [ 'valueX', 'valueY', 'valueZ' ]
}`, the user must specify: `doc.attr[1] == 'valueY'`. Otherwise, all values in
an array are treated as equal alternatives. E.g., when querying for the input
`{ attr: [ 'valueX', 'valueY', 'valueZ' ] }`, the user must specify: `doc.attr
== 'valueY'`.
* **storeValues** (_optional_; type: `string`; default: `"none"`)
This property controls how the view should keep track of the attribute values.
Valid values are:
* **none**: Do not store values with the view.
* **id**: Store information about value presence to allow use of the
`EXISTS()` function.

View File

@ -1,4 +1,4 @@
# Getting started with ArangoSearch views # Getting started with ArangoSearch Views
## The DDL configuration ## The DDL configuration
@ -8,7 +8,9 @@ especially database schemas.
All DDL operations on Views can be done via JavaScript or REST calls. The DDL All DDL operations on Views can be done via JavaScript or REST calls. The DDL
syntax follows the well established ArangoDB guidelines and thus is very syntax follows the well established ArangoDB guidelines and thus is very
similar between JavaScript and REST. This article uses the JavaScript syntax. similar between the [JavaScript interface for views](../../DataModeling/Views/README.md)
and the [HTTP interface for views](../../../HTTP/Views/index.html).This article
uses the JavaScript syntax.
Assume the following collections were initially defined in a database using Assume the following collections were initially defined in a database using
the following commands: the following commands:
@ -40,29 +42,40 @@ v0 = db._createView("ExampleView", "arangosearch", {});
v0 = db._view("ExampleView"); v0 = db._view("ExampleView");
v0.properties({ v0.properties({
links: { links: {
'ExampleCollection0': /* collection Link 0 with additional custom configuration */ /* collection Link 0 with additional custom configuration: */
'ExampleCollection0':
{ {
includeAllFields: true, /* examine fields of all linked collections using default configuration */ /* examine fields of all linked collections,
using default configuration: */
includeAllFields: true,
fields: fields:
{ {
name: /* a field to apply custom configuration that will index English text */ /* a field to apply custom configuration
that will index English text: */
name:
{ {
analyzers: ["text_en"] analyzers: ["text_en"]
}, },
text: /* another field to apply custom that will index Chineese text */ /* another field to apply custom configuration
that will index Chinese text: */
text:
{ {
analyzers: ["text_zh"] analyzers: ["text_zh"]
} }
} }
}, },
'ExampleCollection1': /* collection Link 1 with custom configuration */ /* collection Link 1 with custom configuration: */
'ExampleCollection1':
{ {
includeAllFields: true, /* examine all fields using default configuration */ /* examine all fields using default configuration: */
includeAllFields: true,
fields: fields:
{ {
a: a:
{ {
analyzers: ["text_en"] /* a field to apply custom configuration that will index English text */ /* a field to apply custom configuration
that will index English text: */
analyzers: ["text_en"]
} }
} }
} }

View File

@ -1,4 +1,4 @@
# ArangoSearch views powered by IResearch # ArangoSearch Views powered by IResearch
ArangoSearch is a natively integrated AQL extension making use of the ArangoSearch is a natively integrated AQL extension making use of the
IResearch library. IResearch library.
@ -9,16 +9,16 @@ ArangoSearch allows one to:
* filter documents based on AQL boolean expressions and functions * filter documents based on AQL boolean expressions and functions
* sort the result set based on how closely each document matched the filter * sort the result set based on how closely each document matched the filter
A concept of value 'analysis' that is meant to break up a given value into A concept of value "analysis" that is meant to break up a given value into
a set of sub-values internally tied together by metadata which influences both a set of sub-values internally tied together by metadata which influences both
the filter and sort stages to provide the most appropriate match for the the filter and sort stages to provide the most appropriate match for the
specified conditions, similar to queries to web search engines. specified conditions, similar to queries to web search engines.
In plain terms this means a user can for example: In plain terms this means a user can for example:
* request documents where the 'body' attribute best matches 'a quick brown fox' * request documents where the `body` attribute best matches `a quick brown fox`
* request documents where the 'dna' attribute best matches a DNA sub sequence * request documents where the `dna` attribute best matches a DNA sub sequence
* request documents where the 'name' attribute best matches gender * request documents where the `name` attribute best matches gender
* etc. (via custom analyzers) * etc. (via custom analyzers)
## The IResearch Library ## The IResearch Library
@ -28,7 +28,7 @@ in modern C++, optimized for speed and memory footprint, with source available
from https://github.com/iresearch-toolkit/iresearch from https://github.com/iresearch-toolkit/iresearch
IResearch is the framework for indexing, filtering and sorting of data. IResearch is the framework for indexing, filtering and sorting of data.
The indexing stage can treat each data item as an atom or use custom 'analyzers' The indexing stage can treat each data item as an atom or use custom "analyzers"
to break the data item into sub-atomic pieces tied together with internally to break the data item into sub-atomic pieces tied together with internally
tracked metadata. tracked metadata.
@ -37,7 +37,7 @@ custom implementations of analyzers (used during the indexing and filtering
stages) and scorers (used during the sorting stage) allowing full control over stages) and scorers (used during the sorting stage) allowing full control over
the behavior of the engine. the behavior of the engine.
## Using ArangoSearch views ## Using ArangoSearch Views
To get more familiar with ArangoSearch usage, you may start with [Getting Started](GettingStarted.md) simple guide and then explore details of ArangoSearch in To get more familiar with ArangoSearch usage, you may start with [Getting Started](GettingStarted.md) simple guide and then explore details of ArangoSearch in
[Detailed Overview](DetailedOverview.md), [Detailed Overview](DetailedOverview.md),

View File

@ -1,58 +1,47 @@
ArangoSearch Scorers ArangoSearch Scorers
==================== ====================
ArangoSearch accesses scorers directly by their internal names. The ArangoSearch Scorers are special functions that allow to sort documents from a
name (in upper-case) of the scorer is the function name to be used in the view by their score regarding the analyzed fields.
['SORT' section](../../../AQL/Views/ArangoSearch/index.html#arangosearch-sort).
Function arguments, (excluding the first argument), are serialized as a
string representation of a JSON array and passed directly to the corresponding
scorer. The first argument to any scorer function is the reference to the
current document emitted by the `FOR` statement, i.e. it would be 'doc' for this
statement:
```js Details about their usage in AQL can be found in the
FOR doc IN someView [ArangoSearch `SORT` section](../../../AQL/Views/ArangoSearch/index.html#arangosearch-sorting).
```
IResearch provides a 'bm25' scorer implementing the
[BM25 algorithm](https://en.wikipedia.org/wiki/Okapi_BM25). This scorer
optionally takes 'k' and 'b' positional parameters.
The user is able to run queries with the said scorer, e.g.
```js
SORT BM25(doc, 1.2, 0.75)
```
The function arguments will then be serialized into a JSON representation:
```json
[ 1.2, 0.75 ]
```
and passed to the scorer implementation.
Similarly an administrator may choose to deploy a custom DNA analyzer 'DnaRank'.
The user is then immediately able to run queries with the said scorer, e.g.
```js
SORT DNARANK(doc, 123, 456, "abc", { "def": "ghi" })
```
The function arguments will then be serialized into a JSON representation:
```json
[ 123, 456, "abc", { "def": "ghi" } ]
```
and passed to the scorer implementation.
Runtime-plugging functionality for scores is not available in ArangoDB at this
point in time, so ArangoDB comes with a few default-initialized scores:
- *attribute-name*: order results based on the value of **attribute-name**
- BM25: order results based on the [BM25 algorithm](https://en.wikipedia.org/wiki/Okapi_BM25) - BM25: order results based on the [BM25 algorithm](https://en.wikipedia.org/wiki/Okapi_BM25)
- TFIDF: order results based on the [TFIDF algorithm](https://en.wikipedia.org/wiki/TF-IDF) - TFIDF: order results based on the [TFIDF algorithm](https://en.wikipedia.org/wiki/TF-IDF)
### `BM25()` - Best Matching 25 Algorithm
IResearch provides a 'bm25' scorer implementing the
[BM25 algorithm](https://en.wikipedia.org/wiki/Okapi_BM25). Optionally, free
parameters **k** and **b** of the algorithm typically using for advanced
optimization can be specified as floating point numbers.
`BM25(doc, k, b)`
- *doc* (document): must be emitted by `FOR doc IN someView`
- *k* (number, _optional_): term frequency, the default is _1.2_. *k*
calibrates the text term frequency scaling. A *k* value of *0* corresponds to
a binary model (no term frequency), and a large value corresponds to using raw
term frequency.
- *b* (number, _optional_): determines the scaling by the total text length, the
default is _0.75_. *b* determines the scaling by the total text length.
- b = 1 corresponds to fully scaling the term weight by the total text length
- b = 0 corresponds to no length normalization.
At the extreme values of the coefficient *b*, BM25 turns into the ranking
functions known as BM11 (for b = 1) and BM15 (for b = 0).
### `TFIDF()` - Term Frequency Inverse Document Frequency Algorithm
Sorts documents using the
[**term frequencyinverse document frequency** algorithm](https://en.wikipedia.org/wiki/TF-IDF).
`TFIDF(doc, withNorms)`
- *doc* (document): must be emitted by `FOR doc IN someView`
- *withNorms* (bool, _optional_): specifying whether norms should be used via
**with-norms**, the default is _false_

View File

@ -0,0 +1,15 @@
arangosh&gt; v = db._createView(<span class="hljs-string">"example"</span>, <span class="hljs-string">"arangosearch"</span>);
[ArangoView <span class="hljs-number">119</span>, <span class="hljs-string">"example"</span> (type arangosearch)]
arangosh&gt; v.properties()
{
<span class="hljs-string">"links"</span> : {
},
<span class="hljs-string">"cleanupIntervalStep"</span> : <span class="hljs-number">10</span>,
<span class="hljs-string">"consolidationPolicy"</span> : {
<span class="hljs-string">"segmentThreshold"</span> : <span class="hljs-number">300</span>,
<span class="hljs-string">"threshold"</span> : <span class="hljs-number">0.8500000238418579</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"bytes_accum"</span>
},
<span class="hljs-string">"consolidationIntervalMsec"</span> : <span class="hljs-number">60000</span>
}
arangosh&gt; db._dropView(<span class="hljs-string">"example"</span>)

View File

@ -0,0 +1,5 @@
arangosh&gt; db._createView(<span class="hljs-string">"exampleView"</span>, <span class="hljs-string">"arangosearch"</span>);
[ArangoView <span class="hljs-number">119</span>, <span class="hljs-string">"exampleView"</span> (type arangosearch)]
arangosh&gt; db._dropView(<span class="hljs-string">"exampleView"</span>);
arangosh&gt; db._view(<span class="hljs-string">"exampleView"</span>);
<span class="hljs-literal">null</span>

View File

@ -0,0 +1,5 @@
arangosh&gt; view = db._view(<span class="hljs-string">"example"</span>);
........&gt; <span class="hljs-comment">// or, alternatively</span>
[ArangoView <span class="hljs-number">115</span>, <span class="hljs-string">"example"</span> (type arangosearch)]
arangosh&gt; view = db[<span class="hljs-string">"example"</span>]
[ArangoView <span class="hljs-number">115</span>, <span class="hljs-string">"example"</span> (type arangosearch)]

View File

@ -0,0 +1,5 @@
arangosh&gt; db._views();
[
[ArangoView <span class="hljs-number">115</span>, <span class="hljs-string">"demoView"</span> (type arangosearch)],
[ArangoView <span class="hljs-number">119</span>, <span class="hljs-string">"exampleView"</span> (type arangosearch)]
]

View File

@ -1,2 +1,2 @@
arangosh&gt; db._view(<span class="hljs-string">"demo"</span>); arangosh&gt; db._view(<span class="hljs-string">"demoView"</span>);
<span class="hljs-literal">null</span> [ArangoView <span class="hljs-number">115</span>, <span class="hljs-string">"demoView"</span> (type arangosearch)]

View File

@ -0,0 +1,8 @@
arangosh&gt; v = db._createView(<span class="hljs-string">"example"</span>, <span class="hljs-string">"arangosearch"</span>);
........&gt; <span class="hljs-comment">// or</span>
[ArangoView <span class="hljs-number">149</span>, <span class="hljs-string">"example"</span> (type arangosearch)]
arangosh&gt; v = db._view(<span class="hljs-string">"example"</span>);
[ArangoView <span class="hljs-number">149</span>, <span class="hljs-string">"example"</span> (type arangosearch)]
arangosh&gt; v.drop();
arangosh&gt; db._view(<span class="hljs-string">"example"</span>);
<span class="hljs-literal">null</span>

View File

@ -0,0 +1,14 @@
arangosh&gt; v = db._view(<span class="hljs-string">"demoView"</span>);
[ArangoView <span class="hljs-number">115</span>, <span class="hljs-string">"demoView"</span> (type arangosearch)]
arangosh&gt; v.properties();
{
<span class="hljs-string">"links"</span> : {
},
<span class="hljs-string">"cleanupIntervalStep"</span> : <span class="hljs-number">10</span>,
<span class="hljs-string">"consolidationPolicy"</span> : {
<span class="hljs-string">"segmentThreshold"</span> : <span class="hljs-number">300</span>,
<span class="hljs-string">"threshold"</span> : <span class="hljs-number">0.8500000238418579</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"bytes_accum"</span>
},
<span class="hljs-string">"consolidationIntervalMsec"</span> : <span class="hljs-number">60000</span>
}

View File

@ -0,0 +1,66 @@
arangosh&gt; v = db._view(<span class="hljs-string">"example"</span>);
[ArangoView <span class="hljs-number">122</span>, <span class="hljs-string">"example"</span> (type arangosearch)]
arangosh&gt; v.properties();
........&gt; <span class="hljs-comment">// set cleanupIntervalStep to 12</span>
{
<span class="hljs-string">"links"</span> : {
},
<span class="hljs-string">"cleanupIntervalStep"</span> : <span class="hljs-number">10</span>,
<span class="hljs-string">"consolidationPolicy"</span> : {
<span class="hljs-string">"segmentThreshold"</span> : <span class="hljs-number">300</span>,
<span class="hljs-string">"threshold"</span> : <span class="hljs-number">0.8500000238418579</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"bytes_accum"</span>
},
<span class="hljs-string">"consolidationIntervalMsec"</span> : <span class="hljs-number">60000</span>
}
arangosh&gt; v.properties({<span class="hljs-attr">cleanupIntervalStep</span>: <span class="hljs-number">12</span>});
........&gt; <span class="hljs-comment">// add a link</span>
{
<span class="hljs-string">"cleanupIntervalStep"</span> : <span class="hljs-number">12</span>,
<span class="hljs-string">"consolidationIntervalMsec"</span> : <span class="hljs-number">60000</span>,
<span class="hljs-string">"consolidationPolicy"</span> : {
<span class="hljs-string">"segmentThreshold"</span> : <span class="hljs-number">300</span>,
<span class="hljs-string">"threshold"</span> : <span class="hljs-number">0.8500000238418579</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"bytes_accum"</span>
},
<span class="hljs-string">"links"</span> : {
}
}
arangosh&gt; v.properties({<span class="hljs-attr">links</span>: {<span class="hljs-attr">demo</span>: {}}})
........&gt; <span class="hljs-comment">// remove a link</span>
{
<span class="hljs-string">"cleanupIntervalStep"</span> : <span class="hljs-number">12</span>,
<span class="hljs-string">"consolidationIntervalMsec"</span> : <span class="hljs-number">60000</span>,
<span class="hljs-string">"consolidationPolicy"</span> : {
<span class="hljs-string">"segmentThreshold"</span> : <span class="hljs-number">300</span>,
<span class="hljs-string">"threshold"</span> : <span class="hljs-number">0.8500000238418579</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"bytes_accum"</span>
},
<span class="hljs-string">"links"</span> : {
<span class="hljs-string">"demo"</span> : {
<span class="hljs-string">"analyzers"</span> : [
<span class="hljs-string">"identity"</span>
],
<span class="hljs-string">"fields"</span> : {
},
<span class="hljs-string">"includeAllFields"</span> : <span class="hljs-literal">false</span>,
<span class="hljs-string">"trackListPositions"</span> : <span class="hljs-literal">false</span>,
<span class="hljs-string">"storeValues"</span> : <span class="hljs-string">"none"</span>,
<span class="hljs-string">"id"</span> : <span class="hljs-string">"133"</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"arangosearch"</span>,
<span class="hljs-string">"view"</span> : <span class="hljs-string">"hFFDA13719B2C/122"</span>
}
}
}
arangosh&gt; v.properties({<span class="hljs-attr">links</span>: {<span class="hljs-attr">demo</span>: <span class="hljs-literal">null</span>}})
{
<span class="hljs-string">"cleanupIntervalStep"</span> : <span class="hljs-number">12</span>,
<span class="hljs-string">"consolidationIntervalMsec"</span> : <span class="hljs-number">60000</span>,
<span class="hljs-string">"consolidationPolicy"</span> : {
<span class="hljs-string">"segmentThreshold"</span> : <span class="hljs-number">300</span>,
<span class="hljs-string">"threshold"</span> : <span class="hljs-number">0.8500000238418579</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"bytes_accum"</span>
},
<span class="hljs-string">"links"</span> : {
}
}

View File

@ -0,0 +1,4 @@
arangosh&gt; v = db._view(<span class="hljs-string">"demoView"</span>);
[ArangoView <span class="hljs-number">115</span>, <span class="hljs-string">"demoView"</span> (type arangosearch)]
arangosh&gt; v.name();
demoView

View File

@ -0,0 +1,7 @@
arangosh&gt; v = db._createView(<span class="hljs-string">"example"</span>, <span class="hljs-string">"arangosearch"</span>);
[ArangoView <span class="hljs-number">180</span>, <span class="hljs-string">"example"</span> (type arangosearch)]
arangosh&gt; v.name();
example
arangosh&gt; v.rename(<span class="hljs-string">"exampleRenamed"</span>);
arangosh&gt; v.name();
exampleRenamed

View File

@ -0,0 +1,4 @@
arangosh&gt; v = db._view(<span class="hljs-string">"demoView"</span>);
[ArangoView <span class="hljs-number">115</span>, <span class="hljs-string">"demoView"</span> (type arangosearch)]
arangosh&gt; v.type();
arangosearch

View File

@ -0,0 +1,2 @@
arangosh&gt; view = db._createView(<span class="hljs-string">"myView"</span>, <span class="hljs-string">"arangosearch"</span>, {});
[ArangoView <span class="hljs-number">131393</span>, <span class="hljs-string">"myView"</span> (type arangosearch)]

View File

@ -0,0 +1,2 @@
arangosh&gt; view = db._view(<span class="hljs-string">"myView"</span>);
[ArangoView <span class="hljs-number">131393</span>, <span class="hljs-string">"myView"</span> (type arangosearch)]

View File

@ -0,0 +1,12 @@
arangosh&gt; view.properties();
{
<span class="hljs-string">"links"</span> : {
},
<span class="hljs-string">"cleanupIntervalStep"</span> : <span class="hljs-number">10</span>,
<span class="hljs-string">"consolidationPolicy"</span> : {
<span class="hljs-string">"segmentThreshold"</span> : <span class="hljs-number">300</span>,
<span class="hljs-string">"threshold"</span> : <span class="hljs-number">0.8500000238418579</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"bytes_accum"</span>
},
<span class="hljs-string">"consolidationIntervalMsec"</span> : <span class="hljs-number">60000</span>
}

View File

@ -0,0 +1,12 @@
arangosh&gt; view.properties({<span class="hljs-attr">cleanupIntervalStep</span>: <span class="hljs-number">12</span>});
{
<span class="hljs-string">"cleanupIntervalStep"</span> : <span class="hljs-number">12</span>,
<span class="hljs-string">"consolidationIntervalMsec"</span> : <span class="hljs-number">60000</span>,
<span class="hljs-string">"consolidationPolicy"</span> : {
<span class="hljs-string">"segmentThreshold"</span> : <span class="hljs-number">300</span>,
<span class="hljs-string">"threshold"</span> : <span class="hljs-number">0.8500000238418579</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"bytes_accum"</span>
},
<span class="hljs-string">"links"</span> : {
}
}

View File

@ -0,0 +1,25 @@
arangosh&gt; view.properties({<span class="hljs-attr">links</span>: {<span class="hljs-attr">colA</span>: {<span class="hljs-attr">includeAllFields</span>: <span class="hljs-literal">true</span>}}});
{
<span class="hljs-string">"cleanupIntervalStep"</span> : <span class="hljs-number">12</span>,
<span class="hljs-string">"consolidationIntervalMsec"</span> : <span class="hljs-number">60000</span>,
<span class="hljs-string">"consolidationPolicy"</span> : {
<span class="hljs-string">"segmentThreshold"</span> : <span class="hljs-number">300</span>,
<span class="hljs-string">"threshold"</span> : <span class="hljs-number">0.8500000238418579</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"bytes_accum"</span>
},
<span class="hljs-string">"links"</span> : {
<span class="hljs-string">"colA"</span> : {
<span class="hljs-string">"analyzers"</span> : [
<span class="hljs-string">"identity"</span>
],
<span class="hljs-string">"fields"</span> : {
},
<span class="hljs-string">"includeAllFields"</span> : <span class="hljs-literal">true</span>,
<span class="hljs-string">"trackListPositions"</span> : <span class="hljs-literal">false</span>,
<span class="hljs-string">"storeValues"</span> : <span class="hljs-string">"none"</span>,
<span class="hljs-string">"id"</span> : <span class="hljs-string">"131408"</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"arangosearch"</span>,
<span class="hljs-string">"view"</span> : <span class="hljs-string">"hC4048A4AEAB4/131393"</span>
}
}
}

View File

@ -0,0 +1,40 @@
arangosh&gt; view.properties({<span class="hljs-attr">links</span>: {<span class="hljs-attr">colB</span>: {<span class="hljs-attr">fields</span>: {<span class="hljs-attr">text</span>: {}}}}});
{
<span class="hljs-string">"cleanupIntervalStep"</span> : <span class="hljs-number">12</span>,
<span class="hljs-string">"consolidationIntervalMsec"</span> : <span class="hljs-number">60000</span>,
<span class="hljs-string">"consolidationPolicy"</span> : {
<span class="hljs-string">"segmentThreshold"</span> : <span class="hljs-number">300</span>,
<span class="hljs-string">"threshold"</span> : <span class="hljs-number">0.8500000238418579</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"bytes_accum"</span>
},
<span class="hljs-string">"links"</span> : {
<span class="hljs-string">"colA"</span> : {
<span class="hljs-string">"analyzers"</span> : [
<span class="hljs-string">"identity"</span>
],
<span class="hljs-string">"fields"</span> : {
},
<span class="hljs-string">"includeAllFields"</span> : <span class="hljs-literal">true</span>,
<span class="hljs-string">"trackListPositions"</span> : <span class="hljs-literal">false</span>,
<span class="hljs-string">"storeValues"</span> : <span class="hljs-string">"none"</span>,
<span class="hljs-string">"id"</span> : <span class="hljs-string">"131408"</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"arangosearch"</span>,
<span class="hljs-string">"view"</span> : <span class="hljs-string">"hC4048A4AEAB4/131393"</span>
},
<span class="hljs-string">"colB"</span> : {
<span class="hljs-string">"analyzers"</span> : [
<span class="hljs-string">"identity"</span>
],
<span class="hljs-string">"fields"</span> : {
<span class="hljs-string">"text"</span> : {
}
},
<span class="hljs-string">"includeAllFields"</span> : <span class="hljs-literal">false</span>,
<span class="hljs-string">"trackListPositions"</span> : <span class="hljs-literal">false</span>,
<span class="hljs-string">"storeValues"</span> : <span class="hljs-string">"none"</span>,
<span class="hljs-string">"id"</span> : <span class="hljs-string">"131416"</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"arangosearch"</span>,
<span class="hljs-string">"view"</span> : <span class="hljs-string">"hC4048A4AEAB4/131393"</span>
}
}
}

View File

@ -0,0 +1,27 @@
arangosh&gt; view.properties({<span class="hljs-attr">links</span>: {<span class="hljs-attr">colA</span>: <span class="hljs-literal">null</span>}});
{
<span class="hljs-string">"cleanupIntervalStep"</span> : <span class="hljs-number">12</span>,
<span class="hljs-string">"consolidationIntervalMsec"</span> : <span class="hljs-number">60000</span>,
<span class="hljs-string">"consolidationPolicy"</span> : {
<span class="hljs-string">"segmentThreshold"</span> : <span class="hljs-number">300</span>,
<span class="hljs-string">"threshold"</span> : <span class="hljs-number">0.8500000238418579</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"bytes_accum"</span>
},
<span class="hljs-string">"links"</span> : {
<span class="hljs-string">"colB"</span> : {
<span class="hljs-string">"analyzers"</span> : [
<span class="hljs-string">"identity"</span>
],
<span class="hljs-string">"fields"</span> : {
<span class="hljs-string">"text"</span> : {
}
},
<span class="hljs-string">"includeAllFields"</span> : <span class="hljs-literal">false</span>,
<span class="hljs-string">"trackListPositions"</span> : <span class="hljs-literal">false</span>,
<span class="hljs-string">"storeValues"</span> : <span class="hljs-string">"none"</span>,
<span class="hljs-string">"id"</span> : <span class="hljs-string">"131416"</span>,
<span class="hljs-string">"type"</span> : <span class="hljs-string">"arangosearch"</span>,
<span class="hljs-string">"view"</span> : <span class="hljs-string">"hC4048A4AEAB4/131393"</span>
}
}
}

View File

@ -0,0 +1 @@
arangosh&gt; db._dropView(<span class="hljs-string">"myView"</span>);

View File

@ -221,7 +221,8 @@ var runTestFuncCatch = function (execFunction, testName, expectError) {
}; };
var checkForOrphanTestCollections = function(msg) { var checkForOrphanTestCollections = function(msg) {
var cols = db._collections().map(function(c){ const colsAndViews = db._collections().concat(db._views());
var cols = colsAndViews.map(function(c){
return c.name(); return c.name();
}); });
var orphanColls = []; var orphanColls = [];
@ -253,6 +254,10 @@ var addIgnoreCollection = function(collectionName) {
ignoreCollectionAlreadyThere.push(collectionName); ignoreCollectionAlreadyThere.push(collectionName);
}; };
var addIgnoreView = function(viewName) {
addIgnoreCollection(viewName);
};
var removeIgnoreCollection = function(collectionName) { var removeIgnoreCollection = function(collectionName) {
// print("from now on checking again whether this collection dropped: " + collectionName); // print("from now on checking again whether this collection dropped: " + collectionName);
for (j = 0; j < collectionAlreadyThere.length; j++) { for (j = 0; j < collectionAlreadyThere.length; j++) {
@ -268,6 +273,10 @@ var removeIgnoreCollection = function(collectionName) {
}; };
var removeIgnoreView = function (viewName) {
removeIgnoreCollection(viewName);
};
var checkIgnoreCollectionAlreadyThere = function () { var checkIgnoreCollectionAlreadyThere = function () {
if (ignoreCollectionAlreadyThere.length > 0) { if (ignoreCollectionAlreadyThere.length > 0) {
allErrors += "some temporarily ignored collections haven't been cleaned up: " + allErrors += "some temporarily ignored collections haven't been cleaned up: " +
@ -278,6 +287,6 @@ var checkIgnoreCollectionAlreadyThere = function () {
// Set the first available list of already there collections: // Set the first available list of already there collections:
var err = allErrors; var err = allErrors;
checkForOrphanTestCollections('Collections already there which we will ignore from now on:'); checkForOrphanTestCollections('Collections or views already there which we will ignore from now on:');
print(allErrors + '\n'); print(allErrors + '\n');
allErrors = err; allErrors = err;

View File

@ -20,3 +20,7 @@ db.demo.save({
db._drop("animals"); db._drop("animals");
db._create("animals"); db._create("animals");
collectionAlreadyThere.push("animals"); collectionAlreadyThere.push("animals");
db._dropView("demoView");
db._createView("demoView", "arangosearch");
collectionAlreadyThere.push("demoView");