aerospike
Version:
Aerospike Client Library
1,441 lines (1,395 loc) • 676 kB
TypeScript
import * as Buffer from "buffer";
import { EventEmitter, Stream } from "stream";
/**
* Codes representing each of the various scalar operation types.
*/
export enum ScalarOperations {
/**
* Write operation code.
*/
WRITE,
/**
* Read operation code.
*/
READ,
/**
* Increment operation code.
*/
INCR,
/**
* Prepend operation code.
*/
PREPEND,
/**
* Append operation code.
*/
APPEND,
/**
* Touch operation code.
*/
TOUCH,
/**
* Delete operation code.
*/
DELETE
}
/* TYPES */
/**
* Represents a basic value in an Aerospike bin.
*/
export type PartialAerospikeBinValue = null | undefined | boolean | string | number | Double | BigInt | Buffer | GeoJSON | Array<PartialAerospikeBinValue> | object;
/**
* Represents an object containing one or more `AerospikeBinValues` with associated string keys.
*/
export type AerospikeBins = {
[key: string]: AerospikeBinValue
};
export const _transactionPool: any;
/**
* Represents a complete Aerospike bin value. Bin values can included nested lists and maps.
*/
export type AerospikeBinValue = PartialAerospikeBinValue | PartialAerospikeBinValue[] | Record<string, PartialAerospikeBinValue>;
/**
* Represents an Aerospike Expression. Contains an op number which specifiies the operation type, and properties with values relevant to the operation.
*/
export type AerospikeExp = { op: number, [key: string]: any }[]
/**
* Contains geolocation information releavant to the GEOJSON Aerospike type.
*/
export type GeoJSONType = {
type: string,
coordinates: NumberArray
}
/**
* Represents an array which can contain number or nested number array.
*/
export type NumberArray = number | NumberArray[];
/**
* Callback used to return results in synchronous Aerospike database commands
*/
export type TypedCallback<T> = (error?: AerospikeError, result?: T) => void;
/* CLASSES */
/**
* A record with the Aerospike database consists of one or more record "bins"
* (name-value pairs) and meta-data, including time-to-live and generation; a
* record is uniquely identified by it's key within a given namespace.
*
* @example <caption>Writing a new record with 5 bins while setting a record TTL.</caption>
*
* const Aerospike = require('aerospike')
*
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* write : new Aerospike.WritePolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* }
*
* let bins = {
* int: 123,
* double: 3.1415,
* string: 'xyz',
* bytes: Buffer.from('hello world!'),
* list: [1, 2, 3],
* map: {num: 123, str: 'abc', list: ['a', 'b', 'c']}
* }
* let meta = {
* ttl: 386400 // 1 day
* }
* let key = new Aerospike.Key('test', 'demo', 'myKey')
*
* Aerospike.connect(config)
* .then(client => {
* return client.put(key, bins, meta)
* .then(() => {
* client.get(key)
* .then((record) => {
* console.log(record)
* client.close()
* })
* .catch(error => {
* console.log(record)
* client.close()
* return Promise.reject(error)
* })
* })
* .catch(error => {
* client.close()
* return Promise.reject(error)
* })
* })
* .catch(error => console.error('Error:', error))
*
* @example <caption>Fetching a single database record by it's key.</caption>
*
* const Aerospike = require('aerospike')
*
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* read : new Aerospike.ReadPolicy({socketTimeout : 0, totalTimeout : 0}),
* write : new Aerospike.WritePolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* }
*
* let key = new Aerospike.Key('test', 'demo', 'myKey')
*
* Aerospike.connect(config)
* .then(client => {
* client.put(key, {tags : ['blue', 'pink']})
* .then(() => {
* client.get(key)
* .then(record => {
* console.info('Key:', record.key)
* console.info('Bins:', record.bins)
* console.info('TTL:', record.ttl)
* console.info('Gen:', record.gen)
* })
* .then(() => client.close())
* .catch(error => {
* client.close()
* return Promise.reject(error)
* })
* })
* .catch(error => {
* client.close()
* return Promise.reject(error)
* })
* })
* .catch(error => console.error('Error:', error))
*
* @since v5.0.0
*
* @example <caption>Fetching a batch of records.</caption>
*
* const Aerospike = require('aerospike')
* const op = Aerospike.operations
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* read : new Aerospike.ReadPolicy({socketTimeout : 0, totalTimeout : 0}),
* write : new Aerospike.WritePolicy({socketTimeout : 0, totalTimeout : 0}),
* batch : new Aerospike.BatchPolicy({socketTimeout : 0, totalTimeout : 0})
*
* }
* }
*
* var batchRecords = [
* { type: Aerospike.batchType.BATCH_READ,
* key: new Aerospike.Key('test', 'demo', 'key1'), bins: ['i', 's'] },
* { type: Aerospike.batchType.BATCH_READ,
* key: new Aerospike.Key('test', 'demo', 'key2'), readAllBins: true },
* { type: Aerospike.batchType.BATCH_READ,
* key: new Aerospike.Key('test', 'demo', 'key3'),
* ops:[
* op.read('blob-bin')
* ]}
* ]
* Aerospike.connect(config, function (error, client) {
* if (error) throw error
* client.batchRead(batchRecords, function (error, results) {
* if (error) throw error
* results.forEach(function (result) {
* console.log(result)
*
* })
* client.close()
* })
*
* })
*
* @since v5.0.0
*
* @example <caption>Applying functions on batch of records.</caption>
*
* const Aerospike = require('aerospike')
*
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* read : new Aerospike.ReadPolicy({socketTimeout : 0, totalTimeout : 0}),
* write : new Aerospike.WritePolicy({socketTimeout : 0, totalTimeout : 0}),
*
* }
* }
*
* const batchType = Aerospike.batchType
* var batchRecords = [
* { type: batchType.BATCH_READ,
* key: new Aerospike.Key('test', 'demo', 'key1'),
* bins: ['i', 's'] },
* { type: batchType.BATCH_READ,
* key: new Aerospike.Key('test', 'demo', 'key2'),
* readAllBins: true },
* { type: batchType.BATCH_APPLY,
* key: new Aerospike.Key('test', 'demo', 'key4'),
* policy: new Aerospike.BatchApplyPolicy({
* filterExpression: exp.eq(exp.binInt('i'), exp.int(37)),
* key: Aerospike.policy.key.SEND,
* commitLevel: Aerospike.policy.commitLevel.ALL,
* durableDelete: true
* }),
* udf: {
* module: 'udf',
* funcname: 'function1',
* args: [[1, 2, 3]]
* }
* },
* { type: batchType.BATCH_APPLY,
* key: new Aerospike.Key('test', 'demo', 'key5'),
* policy: new Aerospike.BatchApplyPolicy({
* filterExpression: exp.eq(exp.binInt('i'), exp.int(37)),
* key: Aerospike.policy.key.SEND,
* commitLevel: Aerospike.policy.commitLevel.ALL,
* durableDelete: true
* }),
* udf: {
* module: 'udf',
* funcname: 'function2',
* args: [[1, 2, 3]]
* }
* }
* ]
* Aerospike.connect(config, function (error, client) {
* if (error) throw error
* client.batchApply(batchRecords, udf, function (error, results) {
* if (error) throw error
* results.forEach(function (result) {
* console.log(result)
* })
* })
* })
*/
export class AerospikeRecord {
/**
* Unique record identifier.
*
* @type {Key}
*/
public key: Key;
/**
* Map of bin name to bin value.
*
* @type {AerospikeBins}
*/
public bins: AerospikeBins;
/**
* The record's remaining time-to-live in seconds before it expires.
*
* @type {number}
*/
public ttl: number;
/**
* Record modification count.
*
* @type {number}
*/
public gen: number;
/**
* Construct a new Aerospike Record instance.
*/
constructor(key: KeyOptions, bins: AerospikeBins, metadata?: RecordMetadata);
}
/**
* Transaction class. Each command in a transaction must use the same namespace.
*
* note: By default, open transactions are destroyed when the final client in a process is closed.
* If you need your transaction to persist after the last client has been closed, provide `false` for the
* destroy Transactions argument in {@link Client#close}. For more information on memory management, see {@link Transaction.destroyAll}.
*
* @example <caption>Commit a simple transaction.</caption>
*
* const Aerospike = require('aerospike')
*
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* write : new Aerospike.WritePolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* }
*
* let bins = {
* int: 123,
* double: 3.1415,
* string: 'xyz',
* bytes: Buffer.from('hello world!'),
* list: [1, 2, 3],
* map: {num: 123, str: 'abc', list: ['a', 'b', 'c']}
* }
* let meta = {
* ttl: 386400 // 1 day
* }
* let key = new Aerospike.Key('test', 'demo', 'myKey')
*
* let policy = {
* txn: tran
* };
* ;(async () => {
* let client = await Aerospike.connect(config)
* let tran = new Aerospike.Transaction()
*
*
* await client.put(key, bins, meta, policy)
*
* let get_result = await client.get(key1, policy)
*
* let result = await client.commit(tran)
* await client.close()
* })();
*
* @example <caption>Abort a transaction.</caption>
*
* const Aerospike = require('aerospike')
*
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* read : new Aerospike.ReadPolicy({socketTimeout : 0, totalTimeout : 0}),
* write : new Aerospike.WritePolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* }
*
* let key1 = new Aerospike.Key('test', 'demo', 'myKey')
* let key2 = new Aerospike.Key('test', 'demo', 'myKey')
*
* let record1 = {abc: 123}
* let record2 = {def: 456}
*
* ;(async () => {
* let client = await Aerospike.connect(config)
*
* const policy = {
* txn: tran
* }
*
* await client.put(key4, record2, meta, policy)
*
* const policyRead = {
* txn: tran
* }
*
* let get_result = await client.get(key1, policy) // Will reflect the new value recently put.
*
* await client.put(key2, record2, meta, policy)
*
* let result = await client.abort(tran)
*
* get_result = await client.get(key4) // Will reset to the value present before transaction started.
*
* get_result = await client.get(key5) // Will reset to the value present before transaction started.
*
* await client.close()
* })();
*
* @since v6.0.0
*/
export class Transaction {
/**
* Construct a new Aerospike Transaction instance.
*/
public constructor(reads_capacity?: number, writes_capacity?: number);
/**
* Transaction state enumeration
*/
static state: {
/**
* Transaction is still open.
*/
OPEN: 0,
/**
* Transaction was verified.
*/
VERIFIED: 1,
/**
* Transaction was commited.
*/
COMMITTED: 2,
/**
* Transaction was aborted.
*/
ABORTED: 3
};
/**
* Default Transaction capacity values.
*/
static capacity: {
/**
* Contains the default reeadDefault for aerospike.Transaction
*/
READ_DEFAULT: 128,
/**
* Contains the default writeCapacity for aerospike.Transaction
*/
WRITE_DEFAULT: 128,
};
/**
* Transaction abort status code.
*/
static abortStatus: {
/**
* Abort succeeded.
*/
OK: 0,
/**
* Transaction has already been aborted.
*/
ALREADY_ABORTED: 1,
/**
* Client roll back abandoned. Server will eventually abort the transaction.
*/
ROLL_BACK_ABANDONED: 2,
/**
* Transaction has been rolled back, but client transaction close was abandoned.
* Server will eventually close the transaction.
*/
CLOSE_ABANDONED: 3
};
/**
* Transaction commit status code.
*/
static commitStatus: {
/**
* Commit succeeded.
*/
OK: 0,
/**
* Transaction has already been committed.
*/
ALREADY_COMMITTED: 1,
/**
* Transaction verify failed. Transaction will be aborted.
*/
VERIFY_FAILED: 2,
/**
* Transaction mark roll forward abandoned. Transaction will be aborted when error is not in doubt.
* If the error is in doubt (usually timeout), the commit is in doubt.
*/
MARK_ROLL_FORWARD_ABANDONED: 3,
/**
* Client roll forward abandoned. Server will eventually commit the transaction.
*/
ROLL_FORWARD_ABANDONED: 4,
/**
* Transaction has been rolled forward, but client transaction close was abandoned.
* Server will eventually close the transaction.
*/
CLOSE_ABANDONED: 5
};
private prepareToClose(): void;
private close(): void;
/**
* Destroys all open transactions
*
* @remarks
*
* Use of this API is only necessary when the client is closed with
* the destroyTransactions parameter set is set to false.
* See example below for usage details.
*
* To avoid using this API, close the final connected client in the process
* with destroyTransactions set to true (default is true), and the transaction will be destroyed automatically.
*
* @example
*
* const Aerospike = require('aerospike')
* const Key = Aerospike.Key
*
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* batch : new Aerospike.BatchPolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* }
*
* ;(async () => {
* let tran1 = new Aerospike.Transaction()
* let client = await Aerospike.connect(config)
* client.close(false, true) // `destroyTransactions is true`, tran1 is no longer usable.
*
* let tran2 = new Aerospike.Transaction()
* client = await Aerospike.connect(config)
* client.close(false, true) // `destroyTransactions is false`, tran2 can still be used.
*
* // In order to properly manage the memory at this point, do one of two things before the process exits:
*
* // 1: call destroyAll() to destroy all outstanding transactions from this process.
* tran1.destroyAll()
*
* // 2: reopen and close the final connected client with destroyTransactions
* // client = await Aerospike.connect(config)
* // client.close() // Default will destory the transactions
*
* })();
*
* @since v6.0.0
*/
public destroyAll(): void;
/**
* Get ID for this transaction
*
* @returns Transaction ID
*
* @example
*
* const Aerospike = require('aerospike')
* const Key = Aerospike.Key
*
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* batch : new Aerospike.BatchPolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* }
*
* ;(async () => {
* // Establishes a connection to the server
* let tran = new Aerospike.Transaction()
* let id = tran.getId()
* })();
*
* @since v6.0.0
*/
public getId(): number;
/**
* Get inDoubt status for this transaction.
*
* @returns Transaction inDoubt status
*
* @example
*
* const Aerospike = require('aerospike')
* const Key = Aerospike.Key
*
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* batch : new Aerospike.BatchPolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* }
*
* ;(async () => {
* // Establishes a connection to the server
* let tran = new Aerospike.Transaction()
* let inDoubt = tran.getInDoubt()
* })();
*
* @since v6.0.0
*/
public getInDoubt(): boolean;
/**
*
* Gets the expected number of record reads in the Transaction. Minimum value is 16.
*
* @returns number of records reads in the Transaction.
*
* @example
*
* const Aerospike = require('aerospike')
* const Key = Aerospike.Key
*
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* batch : new Aerospike.BatchPolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* }
*
* ;(async () => {
* // Establishes a connection to the server
* let tran = new Aerospike.Transaction()
* let readsCapacity = tran.getReadsCapacity()
* console.log(readsCapacity) // 128
* })();
*
* @since v6.0.0
*/
public getReadsCapacity(): number;
/**
*
* Gets the current state of the Transaction.
*
* @returns Transaction timeout in seconds
*
* @example
*
* const Aerospike = require('aerospike')
* const Key = Aerospike.Key
*
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* batch : new Aerospike.BatchPolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* }
*
* ;(async () => {
* // Establishes a connection to the server
* let tran = new Aerospike.Transaction()
* let state = tran.getState()
*
* })();
*
*/
public getState(): number;
/**
*
* Gets the current Transaction timeout value.
*
* @returns Transaction timeout in seconds
*
* @example
*
* const Aerospike = require('aerospike')
* const Key = Aerospike.Key
*
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* batch : new Aerospike.BatchPolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* }
*
* ;(async () => {
* // Establishes a connection to the server
* let tran = new Aerospike.Transaction()
* let timeout = tran.getTimeout()
* })();
*
* @since v6.0.0
*/
public getTimeout(): number;
/**
*
* Gets the expected number of record reads in the tran. Minimum value is 16.
*
* @returns number of records reads in the tran.
*
* @example
*
* const Aerospike = require('aerospike')
* const Key = Aerospike.Key
*
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* batch : new Aerospike.BatchPolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* }
*
* ;(async () => {
* // Establishes a connection to the server
* let tran = new Aerospike.Transaction()
* let writesCapacity = tran.getWritesCapacity()
* console.log(writesCapacity) // 128
* })();
*
* @since v6.0.0
*/
public getWritesCapacity(): number;
/**
*
* Set transaction timeout in seconds. The timer starts when the transaction monitor record is created. This occurs when the first command in the transaction is executed.
*
* If the timeout is reached before a commit or abort is called, the server will expire and rollback the transaction.
*
* If the transaction timeout is zero, the server configuration mrt-duration is used. The default mrt-duration is 10 seconds.
*
* Default Client transaction timeout is 0.
*
* @param timeout - Transaction timeout in seconds
*
* @example
*
* const Aerospike = require('aerospike')
* const Key = Aerospike.Key
*
* // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE!
* var config = {
* hosts: '192.168.33.10:3000',
* // Timeouts disabled, latency dependent on server location. Configure as needed.
* policies: {
* batch : new Aerospike.BatchPolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* }
*
* ;(async () => {
* // Establishes a connection to the server
* let tran = new Aerospike.Transaction()
* tran.setTimeout(5) // Set timeout for 5 seconds!
*
* console.log(tran.getTimeout()) // 5
* })();
*
*/
public setTimeout(timeout: number): void;
}
/**
* In the Aerospike database, each record (similar to a row in a relational database) stores
* data using one or more bins (like columns in a relational database). The major difference
* between bins and RDBMS columns is that you don't need to define a schema. Each record can
* have multiple bins. Bins accept the data types listed {@link https://docs.aerospike.com/apidocs/nodejs/#toc4__anchor|here}.
*
* For information about these data types and how bins support them, see {@link https://docs.aerospike.com/server/guide/data-types/scalar-data-types|this}.
*
* Although the bin for a given record or object must be typed, bins in different rows do not
* have to be the same type. There are some internal performance optimizations for single-bin namespaces.
*
*/
export class Bin {
/**
* Construct a new Aerospike Bin instance.
*/
public constructor(name: string, value: AerospikeBinValue, mapOrder?: maps.order);
/**
* Bin name.
*/
name: string;
/**
* Bin name.
*/
value: AerospikeBinValue;
}
export class BatchResult {
/**
* Construct a new BatchResult instance.
*/
public constructor(status: typeof statusNamespace[keyof typeof statusNamespace], record: AerospikeRecord, inDoubt: boolean);
/**
* Result code for this returned record. If not {@link statusNamespace.AEROSPIKE_OK|AEROSPIKE_OK}, the record will be null.
*/
status: typeof statusNamespace[keyof typeof statusNamespace];
/**
* Record result for the requested key. This record will only be populated when the result is
* {@link statusNamespace.AEROSPIKE_OK|AEROSPIKE_OK} or {@link statusNamespace.AEROSPIKE_ERR_UDF|AEROSPIKE_ERR_UDF}.
*/
record: AerospikeRecord;
/**
* It is possible that a write command completed even though the client
* returned this error. This may be the case when a client error occurs
* (like timeout) after the command was sent to the server.
*/
inDoubt: boolean;
}
/**
* Aerospike Query commands perform value-based searches using
* secondary indexes (SI). A Query object, created by calling {@link Client#query},
* is used to execute queries on the specified namespace and set (optional).
* Queries can return a set of records as a {@link RecordStream} or be
* processed using Aeorspike User-Defined Functions (UDFs) before returning to
* the client.
*
* For more information, please refer to the section on
* <a href="http://www.aerospike.com/docs/guide/query.html" title="Aerospike Queries">⇑Queries</a>
* in the Aerospike technical documentation.
*
* To scan _all_ records in a database namespace or set, it is more efficient
* to use {@link Scan.operate}, which provide more fine-grained control over
* execution priority, concurrency, etc.
*
* #### SI Filters
*
* With a SI, the following queries can be made:
*
* - [Equal query]{@link filter.equal} against string or
* numeric indexes
* - [Range query]{@link filter.range} against numeric
* indexes
* - [Point-In-Region query]{@link filter.geoWithinGeoJSONRegion}
* or [Region-Contain-Point query]{@link filter.geoContainsGeoJSONPoint} against geo indexes
*
* See {@link filter} for a list of all supported secondary
* index filter.
*
* Before a secondary index filter can be applied, a SI needs to be
* created on the bins which the index filter matches on. Using the Node.js
* client, a SI can be created using {@link Client#createIndex}.
*
* Currently, only a single SI index filter is supported for
* each query. To do more advanced filtering, a expressions can be
* applied to the query using policy (see below). Alternatively, User-Defined Functions
* (UDFs) can be used to further process the query results on the server.
*
* Previously, predicate filtering was used to perform secondary index queries.
* SI filter predicates have been deprecated since server 5.2, and obsolete since
* server 6.0.
*
* For more information about Predicate Filtering, please refer to the <a
* href="https://www.aerospike.com/docs/guide/predicate.html">⇑Predicate
* Filtering</a> documentation in the Aerospike Feature Guide.
*
* #### Selecting Bins
*
* Using {@link Query#select} it is possible to select a subset of bins which
* should be returned by the query. If no bins are selected, then the whole
* record will be returned. If the {@link Query#nobins} property is set to
* <code>true</code> the only the record meta data (ttl, generation, etc.) will
* be returned.
*
* #### Executing a Query
*
* A query is executed using {@link Query#foreach}. The method returns a {@link
* RecordStream} which emits a <code>data</code> event for each record returned
* by the query. The query can be aborted at any time by calling
* {@link RecordStream#abort}.
*
* #### Applying User-Defined Functions
*
* User-defined functions (UDFs) can be used to filter, transform, and
* aggregate query results. Stream UDFs can process a stream of data by
* defining a sequence of operations to perform. Stream UDFs perform read-only
* operations on a collection of records. Use {@link Query#setUdf} to set the
* UDF parameters (module name, function name and optional list of arguments)
* before executing the query using {@link Query#foreach}.
*
* The feature guides on
* <a href="http://www.aerospike.com/docs/guide/udf.html">⇑User-Defined Functions</a> and
* <a href="http://www.aerospike.com/docs/guide/stream_udf.html">⇑Stream UDFs</a>
* contain more detailed information and examples.
*
* #### Query Aggregation using Stream UDFs
*
* Use Aerospike Stream UDFs to aggregate query results using {@link
* Query#apply}. Aggregation queries work similar to a MapReduce system and
* return a single result value instead of stream of records. Aggregation
* results can be basic data types (string, number, byte array) or collection
* types (list, map).
*
* Please refer to the technical documentation on
* <a href="http://www.aerospike.com/docs/guide/aggregation.html">⇑Aggregation</a>
* for more information.
*
* #### Executing Record UDFs using Background Queries
*
* Record UDFs perform operations on a single record such as updating records
* based on a set of parameters. Using {@link Query#background} you can run a
* Record UDF on the result set of a query. Queries using Records UDFs are run
* in the background on the server and do not return the records to the client.
*
* For additional information please refer to the section on
* <a href="http://www.aerospike.com/docs/guide/record_udf.html">⇑Record UDFs</a>
* in the Aerospike technical documentation.
*
* #### Query pagination
*
* Query pagination allows for queries return records in pages rather than all at once.
* To enable query pagination, the query property {@link paginate} must be true
* and the previously stated query property {@link Query.maxRecords} must be set to a
* nonzero positive integer in order to specify a maximum page size.
*
* When a page is complete, {@link RecordStream} event {@link RecordStream#on 'error'} will
* emit a {@link Query#queryState} object containing a serialized version of the query.
* This serialized query, if be assigned back to {@link Query#queryState}, allows the query
* to retrieve the next page of records in the query upon calling {@link Query#foreach}.
* If {@link Query#queryState} is undefined, pagination is not enabled or the query has completed.
* If {@link RecordStream#on 'error'} emits an <code>undefined</code> object, either {@link paginate}
* is not <code>true</code>, or the query has successfully returned all the specified records.
*
* For additional information and examples, please refer to the {@link paginate} section
* below.
*
* @see {@link Client#query} to create new instances of this class.
*
* @example
*
* const Aerospike = require('aerospike')
* const namespace = 'test'
* const set = 'demo'
*
* Aerospike.connect((error, client) => {
* if (error) throw error
* var index = {
* ns: namespace,
* set: set,
* bin: 'tags',
* index: 'tags_idx',
* type: Aerospike.indexType.LIST,
* datatype: Aerospike.indexDataType.STRING
* }
* client.createIndex(index, (error, job) => {
* if (error) throw error
* job.waitUntilDone((error) => {
* if (error) throw error
*
* var query = client.query('test', 'demo')
* const queryPolicy = { filterExpression: exp.keyExist('uniqueExpKey') }
* query.select('id', 'tags')
* query.where(Aerospike.filter.contains('tags', 'green', Aerospike.indexType.LIST))
* var stream = query.foreach(queryPolicy)
* stream.on('error', (error) => {
* console.error(error)
* throw error
* })
* stream.on('data', (record) => {
* console.info(record)
* })
* stream.on('end', () => {
* client.close()
* })
* })
* })
* })
*/
export class Query {
/**
* Aerospike Client Instance
*/
public client: Client;
/**
* Namespace to query.
*/
public ns: string;
/**
* Name of the set to query.
*/
public set: string;
/**
* Filters to apply to the query.
*
* *Note:* Currently, a single index filter is supported. To do more
* advanced filtering, you need to use a user-defined function (UDF) to
* process the result set on the server.
*/
public filters: filter.SindexFilterPredicate[];
/**
* List of bin names to be selected by the query. If a query specifies bins to
* be selected, then only those bins will be returned. If no bins are
* selected, then all bins will be returned (unless {@link Query#nobins} is
* set to `true`).
*/
public selected: string[];
/**
* If set to `true`, the query will return only meta data, and exclude bins.
*/
public nobins: boolean;
/**
* User-defined function parameters to be applied to the query executed using
* {@link Query#foreach}.
*/
public udf: UDF;
/**
* Approximate number of records to return to client.
*
* When {@link paginate} is <code>true</code>,
* then maxRecords will be the page size if there are enough records remaining in the query to fill the page size.
*
* When {@link paginate} is <code>false</code>, this number is divided by the number of nodes involved in the scan,
* and actual number of records returned may be less than maxRecords if node record counts are small and unbalanced across nodes.
*/
public maxRecords?: number;
/**
* Specifies operations to be executed when {@link operate} is called.
*/
public ops?: operations.Operation[];
/**
* If set to <code>true</code>, paginated queries are enabled. In order to receive paginated
* results, the {@link maxRecords} property must assign a nonzero integer value.
*
* @example <caption>Asynchronous pagination over a set of thirty records with {@link Query#foreach}.</caption>
*
* const Aerospike = require('./lib/aerospike');
* // Define host configuration
* let config = {
* hosts: '34.213.88.142:3000',
* policies: {
* batchWrite : new Aerospike.BatchWritePolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* };
*
* var batchRecords = []
* for(let i = 0; i < 30; i++){
* batchRecords.push({
* type: Aerospike.batchType;.BATCH_WRITE,
* key: new Aerospike.Key('test', 'demo', 'key' + i),
* ops:[Aerospike.operations.write('exampleBin', i)]
* })
* }
*
* ;(async function() {
* try {
* client = await Aerospike.connect(config)
* await client.truncate('test', 'demo', 0)
* await client.batchWrite(batchRecords, {socketTimeout : 0, totalTimeout : 0})
*
* const query = client.query('test', 'demo', { paginate: true, maxRecords: 10})
* do {
* const stream = query.foreach()
* stream.on('error', (error) => { throw error })
* stream.on('data', (record) => {
* console.log(record.bins)
* })
* await new Promise(resolve => {
* stream.on('end', (queryState) => {
* query.queryState = queryState
* resolve()
* })
* })
* } while (query.queryState !== undefined)
*
* } catch (error) {
* console.error('An error occurred at some point.', error)
* process.exit(1)
* } finally {
* if (client) client.close()
* }
* })()
*
* @example <caption>Asynchronous pagination over a set of thirty records with {@link Query#results}</caption>
*
*
* const Aerospike = require('./lib/aerospike');
* // Define host configuration
* let config = {
* hosts: '34.213.88.142:3000',
* policies: {
* batchWrite : new Aerospike.BatchWritePolicy({socketTimeout : 0, totalTimeout : 0}),
* }
* };
*
* var batchRecords = []
* for(let i = 0; i < 30; i++){
* batchRecords.push({
* type: Aerospike.batchType.BATCH_WRITE,
* key: new Aerospike.Key('test', 'demo', 'key' + i),
* ops:[Aerospike.operations.write('exampleBin', i)]
* })
* }
*
*
* ;(async function() {
* try {
* client = await Aerospike.connect(config)
* await client.truncate('test', 'demo', 0)
* await client.batchWrite(batchRecords, {socketTimeout : 0, totalTimeout : 0})
*
* const query = client.query('test', 'demo', { paginate: true, maxRecords: 11})
*
* let allResults = []
* let results = await query.results()
* allResults = [...allResults, ...results]
*
*
* results = await query.results()
* allResults = [...allResults, ...results]
*
* results = await query.results()
* allResults = [...allResults, ...results]
*
* console.log("Records returned in total: " + allResults.length) // Should be 30 records
* } catch (error) {
* console.error('An error occurred at some point.', error)
* process.exit(1)
* } finally {
* if (client) client.close()
* }
* })()
*
*/
public paginate?: boolean;
/**
* Used when querying partitions to manage the query. For internal use only.
*/
public partFilter?: PartFilter;
/**
* If set to <code>true</code>, the query will return records belonging to the partitions specified
* in {@link Query#partFilter}.
*/
public pfEnabled?: boolean;
/**
* The time-to-live (expiration) of the record in seconds.
*
* There are also special values that can be set in the record TTL For details
*
* Note that the TTL value will be employed ONLY on background query writes.
*/
public ttl: number;
/**
* If set to a valid serialized query, calling {@link Query.foreach} will allow the next page of records to be queried while preserving the progress
* of the previous query. If set to <code>null</code>, calling {@link Query.foreach} will begin a new query.
*/
public queryState?: number[];
/**
* Construct a Query instance.
*
* @param client - A client instance.
* @param ns - The namescape.
* @param set - The name of a set.
* @param options - Query options.
* *
*/
constructor(client: Client, ns: string, set: string, options?: QueryOptions | null);
/**
*
* Checks compiliation status of a paginated query.
*
* If <code>false</code> is returned, there are no more records left in the query, and the query is complete.
* If <code>true</code> is returned, calling {@link Query#foreach} will continue from the state specified by {@link Query#queryState}.
*
* @returns `true` if another page remains.
*/
public hasNextPage(): boolean;
/**
* Sets {@link Query#queryState} to the value specified by the <code>state</code> argument.
*
* setter function for the {@link Query#queryState} member variable.
*
* @param state - serialized query emitted from the {@link RecordStream#on 'error'} event.
*/
public nextPage(state: number[]): void;
/**
* Specify the begin and count of the partitions
* to be queried by the Query foreach op.
*
* If a Query specifies partitions begin and count,
* then only those partitons will be queried and returned.
* If no partitions are specified,
* then all partitions will be queried and returned.
*
* @param begin - Start partition number to query.
* @param count - Number of partitions from the start to query.
* @param digest - Start from this digest if it is specified.
*/
public partitions(begin: number, count: number, digest?: Buffer | null): void;
/**
* Specify the names of bins to be selected by the query.
*
* If a query specifies bins to be selected, then only those bins
* will be returned. If no bins are selected, then all bins will be returned.
* (Unless {@link Query.nobins} is set to <code>true</code>.)
*
* @param bins - List of bin names or multiple bin names to return.
* @return {void}
*/
public select(bins: string[]): void;
/**
*
* @param bins - A spread of bin names to return.
* @return {void}
*/
public select(...bins: string[]): void;
/**
* Applies a SI to the query.
*
* Use a SI to limit the results returned by the query.
* This method takes SI created using the {@link
* filter | filter module} as argument.
*
* @param predicate - The index filter to
* apply to the function.
*
* @example <caption>Applying a SI filter to find all records
* where the 'tags' list bin contains the value 'blue':</caption>
*
* const Aerospike = require('aerospike')
*
* Aerospike.connect().then(client => {
* let query = client.query('test', 'demo')
*
* let tagsFilter = Aerospike.filter.contains('tags', 'blue', Aerospike.indexType.LIST)
* query.where(tagsFilter)
*
* let stream = query.foreach()
* stream.on('data', record => { console.info(record.bins.tags) })
* stream.on('error', error => { throw error })
* stream.on('end', () => client.close())
* })
*
* @see {@link filter} to create SI filters.
*/
public where(predicate: filter.SindexFilterPredicate): void;
private setSindexFilter(sindexFilter: filter.SindexFilterPredicate): void;
/**
*
* Set user-defined function parameters to be applied to the query.
*
* @param udfModule - UDF module name.
* @param udfFunction - UDF function name.
* @param udfArgs - Arguments for the function.
*/
public setUdf(udfModule: string, udfFunction: string, udfArgs?: AerospikeBinValue[] | null): void;
/**
* Asynchronously executes the query and returns each result item
* through the stream.
*
* *Applying a Stream UDF to the query results*
*
* A stream UDF can be applied to the query to filter, transform and aggregate
* the query results. The UDF parameters need to be set on the query object
* using {@link Query#setUdf} before the query is executed.
*
* If a UDF is applied to the query, the resulting stream will return
* the results of the UDF stream function. Record meta data and the record keys
* will not be returned.
*
* For aggregation queries that return a single result value instead of a
* stream of values, you should use the {@link Query#apply} method instead.
*
* @param policy - The Query Policy to use for this command.
* @param dataCb - The function to call when the
* command completes with the results of the command; if no callback
* function is provided, the method returns a <code>Promise<code> instead.
* @param errorCb - Callback function called when there is an error.
* @param endCb - Callback function called when an operation has completed.
*
* @returns {@link RecordStream}
*/
public foreach(policy?: policy.QueryPolicy | null, dataCb?: (data: AerospikeRecord) => void, errorCb?: (error: Error) => void, endCb?: () => void): RecordStream;
/**
* Executes the query and collects the results into an array. On paginated queries,
* preparing the next page is also handled automatically.
*
*
* This method returns a Promise that contains the query results
* as an array of records, when fulfilled. It should only be used if the query
* is expected to return only few records; otherwise it is recommended to use
* {@link Query.foreach}, which returns the results as a {@link RecordStream}
* instead.
*
* If pagination is enabled, the data emitted from the {@link RecordStream#on 'error'}
* event will automatically be assigned to {@link Query.queryState}, allowing the next page
* of records to be queried if {@link Query.foreach} or {@link Query.results} is called.
*
*
* @param policy - The Query Policy to use for this command.
*
* @returns A promise that resolves with an Aerospike Record.
*/
public results(policy?: policy.QueryPolicy | null): Promise<AerospikeRecord[]>;
/**
* Applies a user-defined function (UDF) to aggregate the query results.
*
* The aggregation function is called on both server and client (final reduce). Therefore, the Lua script files must also reside on both server and client.
*
* @param udfModule - UDF module name.
* @param udfFunction - UDF function name.
* @param udfArgs - Arguments for the function.
* @param policy - The Query Policy to use for this command.
*
* @returns A promise that resolves with an Aerospike bin value.
*
*/
public apply(udfModule: string, udfFunction: string, udfArgs?: AerospikeBinValue[] | null, policy?: policy.QueryPolicy | null): Promise<AerospikeBinValue>;
/**
* @param udfModule - UDF module name.
* @param udfFunction - UDF function name.
* @param callback - The function to call when the command completes.
*
*/
public apply(udfModule: string, udfFunction: string, callback: TypedCallback<AerospikeBinValue>): void;
/**
* @param udfModule - UDF module name.
* @param udfFunction - UDF function name.
* @param udfArgs - Arguments for the function.
* @param callback - The function to call when the command completes.
*
*/
public apply(udfModule: string, udfFunction: string, udfArgs?: AerospikeBinValue[] | null, callback?: TypedCallback<AerospikeBinValue>): void;
/**
* @param udfModule - UDF module name.
* @param udfFunction - UDF function name.
* @param udfArgs - Arguments for the function.
* @param policy - The Query Policy to use for this command.
* @param callback - The function to call when the command completes.
*
*/
public apply(udfModule: string, udfFunction: string, udfArgs?: AerospikeBinValue[], policy?: policy.QueryPolicy | null, callback?: TypedCallback<AerospikeBinValue>): void;
/**
* Applies a user-defined function (UDF) on records that match the query filter.
* Records are not returned to the client.
*
* When a background query is initiated, the client will not wait
* for results from the database. Instead a {@link Job} instance will be
* returned, which can be used to query the query status on the database.
*
* @param udfModule - UDF module name.
* @param udfFunction - UDF function name.
* @param udfArgs - Arguments for the function.
* @param policy - The Write Policy to use for this command.
* @param queryID - Job ID to use for the query; will be assigned
* randomly if zero or undefined.
*
* @returns Promise that resolves to a {@link Job} instance.
*/
public background(udfModule: string, udfFunction: string, udfArgs?: AerospikeBinValue[] | null, policy?: policy.WritePolicy | null, queryID?: number | null): Promise<Job>;
/**
* @param udfModule - UDF module name.
* @param udfFunction - UDF function name.
* @param callback - The function to call when the command completes.
*
*/
public background(udfModule: string, udfFunction: string, callback: TypedCallback<Job>): void;
/**
* @param udfModule - UDF module name.
* @param udfFunction - UDF function name.
* @param udfArgs - Arguments for the function.
* @param callback - The function to call when the command completes.
*
*/
public background(udfModule: string, udfFunction: string, udfArgs?: AerospikeBinValue[] | null, callback?: TypedCallback<Job>): void;
/**
* @param udfModule - UDF module name.
* @param udfFunction - UDF function name.
* @param udfArgs - Arguments for the function.
* @param policy - The Write Policy to use for this command.
* @param callback - The function to call when the command completes.
*
*/
public background(udfModule: string, udfFunction: string, udfArgs?: AerospikeBinValue[] | null, policy?: policy.WritePolicy | null, callback?: TypedCallback<Job>): void;
/**
* @param udfModule - UDF module name.
* @param udfFunction - UDF function name.
* @param udfArgs - Arguments for the function.
* @param policy - The Write Policy to use for this command.
* @param queryID - Job ID to use for the query; will be assigned
* randomly if zero or undefined.
* @param callback - The function to call when the command completes.
*
*/
public background(udfModule: string, udfFunction: string, udfArgs?: AerospikeBinValue[] | null, policy?: policy.WritePolicy | null, queryID?: number | null, callback?: TypedCallback<Job> | null): void;
/**
* Applies write operations to all matching records.
*
* Performs a background query and applies one or more write
* operations to all records that match the query filter(s). Neither the
* records nor the results of the operations are returned to the client.
* Instead a {@link Job} instance will be returned, which can be used to query
* the query status.
*
* This method requires server >= 3.7.0.
*
* @param operations - List of write
* operations to perform on the matching records.
* @param policy - The Query Policy to use for this command.
* @param queryID - Job ID to use for the query; will be assigned
* randomly if zero or undefined.
*
* @returns Promise that resolves to a Job instance.
*
* @since v3.14.0
*
* @example <caption>Increment count