Querying

Queries are handled through table scanners which provide the ability to query cells from a table by applying various scan predicates and options.

 

In order to issue a query that return a specific set of cells from a table you have to obtain a ITableScanner from a ITable interface, for example:

var connectionString = "Provider=Hyper;Uri=net.tcp://localhost";
using (var context = Context.Create(connectionString))
using (var client = context.CreateClient())
using (var ns = client.OpenNamepace("example"))
using (var table = ns.OpenTable("users"))
using (var scanner = table.CreateScanner())
   foreach (cell cell in scanner) {
      // process cell
   }
}

 

Scan specification

The ScanSpec class represents the scan specification, which defines the columns to be considered during query evaluation, the query predicates and options. The scan specification must be passed to the CreateScanner method, for example:

var scanSpec = 
   new ScanSpec()
      .AddColumn("cf1")             // all cells in column family cf1
      .AddColumn("cf2:cq")          // all cells in column family cf2 with column qualifier cq
      .AddColumn("cf3:/abc[0-9]/")  // all cells in cf3 where column qualifier matches the regex
      .AddColumn("cf4:");           // all cells in cf4 where no column qualifier exists
      .AddColumn("cf5:^xyz");       // all cells in cf5 where the column qualifier starts with the prefix specified

using (var scanner = table.CreateScanner(scanSpec))
   Cell cell;
   while (scanner.Next(out cell)) {
      // process cell
   }
}

Alternative the ScanSpecBuilder provides the ability to create a scan specification using a fluent interface, for example:

var scanSpec = 
   ScanSpecBuilder
      .Create()
         .WithColumns("cf1", "cf2:cq", "cf3:/abc[0-9]/", "cf4:", "cf5:^xyz")
      .Build();

using (var scanner = table.CreateScanner(scanSpec ))
   Cell cell;
   while (scanner.Next(out cell)) {
      // process cell
   }
}

 

Row predicate

The row predicate allows you to specify a set of rows or row intervals (RowInterval) to be considered during query evaluation:

var scanSpec = 
   new ScanSpec()
      .AddRow("rk1")                      // all cells in row rk1
      .AddRow("rk2", "rk3")               // all cells in row rk2 and rk3
      .AddRowInterval(
         new RowInterval("rka", "rkz"));  // all cells in the row interval [rka < rkz]

Or using ScanSpecBuilder, for example:

var scanSpec = 
   ScanSpecBuilder
      .Create()
         .WithColums()                             // all columns
         .WithRows("rk1")                          // all cells in row rk1
         .WithRows("rk2", "rk3")                   // all cells in row rk2 and rk3
         .WithRows(new RowInterval("rka", "rkz"))  // all cells in the row interval [rka < rkz]
      .Build();

Row predicates cannot be combined with cell predicates (see below).

 

Cell predicate

The cell predicate allows you specify a set of cells or cell intervals (CellInterval) to be considered during query evaluation:

var scanSpec = 
   new ScanSpec()
      .AddCell("rk1", "cf1", "cq1")  // all cells in row rk1 and column cf1:cq1
      .AddCell("rk2", "cf2", null)   // all cells in row rk1 and column family cf1
      .AddCellInterval(
         new CellInterval(
            "rka", "cf1", "cq1",
            "rkz", "cf2", null));    // all cells in the cell interval [rka cf1:cq1 < rkz cf2]

Or using ScanSpecBuilder, for example:

var scanSpec = 
   ScanSpecBuilder
      .Create()
         .WithColums()
         .WithCells("rk1", "cf1", "cq1")  // all cells in row rk1 and column cf1:cq1
         .WithCells("rk2", "cf2", null)   // all cells in row rk1 and column family cf1
         .WithCells(
            new CellInterval(
              "rka", "cf1", "cq1",
              "rkz", "cf2", null))        // all cells in the cell interval [rka cf1:cq1 < rkz cf2]
      .Build();

Cell predicates cannot be combined with row predicates.

 

Result set

The ITableScanner interface inherits from IEnumerable<Cell> and implements GetEnumerator(), therefore the foreach statement and any of the LINQ extension methods can be used with a scanner:

using (var scanner = table.CreateScanner())
   foreach (cell cell in scanner) {
      // process cell
   }
}

Alternative the scanner's Next and Move methods provide the ability to iterate through the result set:

using (var scanner = table.CreateScanner())
   Cell cell;
   while (scanner.Next(out cell)) {
      // process cell
   }
}

Or the Move method which provides the ability to re-use the cell instance:

using (var scanner = table.CreateScanner())
   var cell = new Cell();
   while (scanner.Move(cell)) {
      // process cell
   }
}