

The AWS Mobile SDK for Xamarin is now included in the AWS SDK for .NET. This guide references the archived version of the Mobile SDK for Xamarin.

# Amazon DynamoDB
<a name="dynamodb"></a>

## What is Amazon DynamoDB?
<a name="what-is-amazon-dynamodb"></a>

 [Amazon DynamoDB](https://aws.amazon.com/dynamodb/) is a fast, highly scalable non-relational database service. DynamoDB removes traditional scalability limitations on data storage while maintaining low latency and predictable performance.

## Key Concepts
<a name="key-concepts"></a>

The DynamoDB data model concepts include tables, items, and attributes.

### Tables
<a name="tables"></a>

In Amazon DynamoDB, a database is a collection of tables. A table is a collection of items and each item is a collection of attributes.

In a relational database, a table has a predefined schema such as the table name, primary key, list of its column names and their data types. All records stored in the table must have the same set of columns. In contrast, DynamoDB only requires that a table has a primary key, but does not require you to define all of the attribute names and data types in advance.

To learn more about working with tables, see [Working with Tables in DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html).

### Items and Attributes
<a name="items-and-attributes"></a>

Individual items in a DynamoDB table can have any number of attributes, although there is a limit of 400 KB on the item size. An item size is the sum of lengths of its attribute names and values (binary and UTF-8 lengths).

Each attribute in an item is a name-value pair. An attribute can be single-valued or multi-valued set. For example, a book item can have title and authors attributes. Each book has one title but can have many authors. The multi-valued attribute is a set; duplicate values are not allowed.

For example, consider storing a catalog of products in DynamoDB. You can create a table, ProductCatalog, with the Id attribute as its primary key. The primary key uniquely identifies each item, so that no two products in the table can have the same ID.

To learn more about working with items, see [Working with Items in DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html).

### Data Types
<a name="data-types"></a>

Amazon DynamoDB supports the following data types:
+  **Scalar types** – Number, String, Binary, Boolean, and Null.
+  **Multi-valued types** – String Set, Number Set, and Binary Set.
+  **Document types** – List and Map.

For more information about Scalar Data Types, Multi-Valued Data Types, and Document Data Types, see [DynamoDB Data Types](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DataModel.html#DataModel.DataTypes).

### Primary Key
<a name="primary-key"></a>

When you create a table, in addition to the table name, you must specify the primary key of the table. The primary key uniquely identifies each item in the table, so that no two items can have the same key. DynamoDB supports the following two types of primary keys:
+  **Hash Key**: The primary key is made of one attribute, a hash attribute. DynamoDB builds an unordered hash index on this primary key attribute. Each item in the table is uniquely identified by its hash key value.
+  **Hash and Range Key**: The primary key is made of two attributes. The first attribute is the hash attribute and the second one is the range attribute. DynamoDB builds an unordered hash index on the hash primary key attribute, and a sorted range index on the range primary key attribute. Each item in the table is uniquely identified by the combination of its hash and range key values. It is possible for two items to have the same hash key value, but those two items must have different range key values.

### Secondary Indexes
<a name="secondary-indexes"></a>

When you create a table with a hash and range key, you can optionally define one or more secondary indexes on that table. A secondary index lets you query the data in the table using an alternate key, in addition to queries against the primary key.

DynamoDB supports two kinds of secondary indexes: local secondary indexes and global secondary indexes.
+  **Local secondary index**: An index that has the same hash key as the table, but a different range key.
+  **Global secondary index**: An index with a hash and range key that can be different from those on the table.

You can define up to 5 global secondary indexes and 5 local secondary indexes per table. For more information, see [Improving Data Access with Secondary Indexes in DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html) in the DynamoDB Developer Guide.

### Query and Scan
<a name="query-and-scan"></a>

In addition to using primary keys to access items, Amazon DynamoDB also provides two APIs for searching the data: Query and Scan. We recommend that you read [Guidelines for Query and Scan](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScanGuidelines.html) in the DynamoDB Developer Guide to familiarize yourself with some best practices.

#### Query
<a name="query"></a>

A Query operation finds items in a table or a secondary index using only primary key attribute values. You must provide a hash key attribute name and a distinct value to search for. You can optionally provide a range key attribute name and value, and use a comparison operator to refine the search results.

For sample queries, see:
+  [Using the Document Model](dynamodb-integration-docmodel.md) 
+  [Using the Object Persistence Model](dynamodb-integration-objectpersistencemodel.md) 
+  [Using the DynamoDB Service Level APIs](dynamodb-integration-lowlevelapi.md) 

For more information on Query, see [Query](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#QueryAndScan.Query) in the DynamoDB Developer Guide.

#### Scan
<a name="scan"></a>

A Scan operation reads every item in a table or a secondary index. By default, a Scan operation returns all of the data attributes for every item in the table or index. You can use the ProjectionExpression parameter so that Scan only returns some of the attributes, rather than all of them.

For sample scans, see:
+  [Using the Document Model](dynamodb-integration-docmodel.md) 
+  [Using the Object Persistence Model](dynamodb-integration-objectpersistencemodel.md) 
+  [Using the DynamoDB Service Level APIs](dynamodb-integration-lowlevelapi.md) 

For more information on Scan, see [Scan](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#QueryAndScan.Scan) in the DynamoDB Developer Guide.

## Project Setup
<a name="project-setup"></a>

### Prerequisites
<a name="prerequisites"></a>

To use DynamoDB in your application, you’ll need to add the SDK to your project. To do so, follow the instructions in [Setting Up the AWS Mobile SDK for .NET and Xamarin](setup.md).

### Create a DynamoDB Table
<a name="create-a-dynamodb-table"></a>

To create a table, go to the [DynamoDB console](https://console.aws.amazon.com/dynamodb/home) and follow these steps:

1. Click **Create Table**.

1. Enter the name of the table.

1. Select **Hash** as the primary key type.

1. Select a type and enter a value for the hash attribute name. Click **Continue**.

1. On the **Add Indexes** page, if you plan to to use global secondary indexes, set **Index Type** to “Global Secondary Index” and under **Index Hash Key**, enter a value for the secondary index. This will allow you to query and scan using both the primary index and secondary index. Click **Add Index To Table**, and then click **Continue**. To skip using global secondary indexes, click **Continue**.

1. Set the read and write capacity to your desired levels. For more information on configuring capacity, see [Provisioned Throughput in Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughputIntro.html). Click **Continue**.

1. On the next screen, enter a notification email to create throughput alarms, if desired. Click **Continue**.

1. On the summary page, click **Create**. DynamoDB will create your database.

### Set Permissions for DynamoDB
<a name="set-permissions-for-dynamodb"></a>

To use DynamoDB in an application, you must set the correct permissions. The following IAM policy allows the user to delete, get, put, query, scan, and update items in a specific DynamoDB table, which is identified by [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html):

```
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:DeleteItem",
        "dynamodb:GetItem",
        "dynamodb:PutItem",
        "dynamodb:Query",
        "dynamodb:Scan",
        "dynamodb:UpdateItem"
      ],
      "Resource": "arn:aws:dynamodb:us-west-2:123456789012:table/MyTable"
    }
  ]
}
```

You can modify policies in the [IAM console](https://console.aws.amazon.com/iam/). You should add or remove allowed actions based on the needs of your app.

To learn more about IAM policies, see [Using IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_Introduction.html).

To learn more about DynamoDB-specific policies, see [Using IAM to Control Access to DynamoDB Resources](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/UsingIAMWithDDB.html) in the DynamoDB Developer Guide.

## Integrating DynamoDB with your Application
<a name="integrating-dynamodb-with-your-application"></a>

The AWS Mobile SDK for .NET and Xamarin provides a high-level library for working with DynamoDB. You can also make requests directly against the low-level DynamoDB API, but for most use cases the high-level library is recommended. The AmazonDynamoDBClient is an especially useful part of the high-level library. Using this class, you can perform various create, read, update, and delete (CRUD) operations and execute queries.

The AWS Mobile SDK for .NET and Xamarin allows you to make calls using APIs from the AWS SDK for .NET to work with DynamoDB. All of the APIs are available in the AWSSDK.dll. For information about downloading the AWS SDK for .NET, see [AWS SDK for .NET](https://aws.amazon.com/sdk-for-net/).

There are three ways you can interact with DynamoDB in your Xamarin application:
+  **Document Model**: This API provides wrapper classes around the low-level DyanmoDB API to further simplify your programming tasks. The Table and Document are the key wrapper classes. You can use the document model for the data operations such as create, retrieve, update and delete items. The API is available in the Amazon.DynamoDB.DocumentModel namespace.
+  **Object Persistence Model**: The Object Persistence API enables you to map your client-side classes to the DynamoDB tables. Each object instance then maps to an item in the corresponding tables. The DynamoDBContext class in this API provides methods for you to save client-side objects to a table, retrieve items as objects and perform query and scan. You can use the Object Persistence model for the data operations such as create, retrieve, update and delete items. You must first create your tables using the Service Client API and then use the object persistence model to map your classes to the tables. The API is available in the Amazon.DynamoDB.DataModel namespace.
+  **Service Client API**: This is the protocol-level API that maps closely to the DynamoDB API. You can use this low-level API for all table and item operations such as create, update, delete table and items. You can also query and scan your tables. This API is available in the Amazon.DynamoDB namespace.

These three models are explored in-depth in the following topics:

**Topics**

# Using the Document Model
<a name="dynamodb-integration-docmodel"></a>

The Document Model provides wrapper classes around the low-level .NET API. The Table and Document are the key wrapper classes. You can use the Document Model to create, retrieve, update and delete items. To create, update and delete tables, you must use the low-level API. For instructions on how to use the low-level API, see [Using the DynamoDB Service Level APIs](dynamodb-integration-lowlevelapi.md). The low-level API is available in the Amazon.DynamoDB.DocumentModel namespace.

To learn more about the Document Model, see [.NET Document Model](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DotNetSDKMidLevel.html).

## Create a DynamoDB Client
<a name="create-a-dynamodb-client"></a>

To create a DynamoDB client:

```
var client = new AmazonDynamoDBClient(credentials,region);
DynamoDBContext context = new DynamoDBContext(client);
```

## CRUD Operations
<a name="crud-operations"></a>

### Save an Item
<a name="save-an-item"></a>

Create an item:

```
Table table = Table.LoadTable(client, "Books");
id = Guid.NewGuid().ToString();
var books = new Document();
books["Id"] = id;
books["Author"] = "Mark Twain";
books["Title"] = "Adventures of Huckleberry Finn";
books["ISBN"] = "112-111111";
books["Price"] = "10";
```

Save an item to a DynamoDB table:

```
var book = await table.PutItemAsync(books);
```

### Retrieve an Item
<a name="retrieve-an-item"></a>

To retrieve an item:

```
public async Task GetItemAsync(AWSCredentials credentials, RegionEndpoint region)
{
      var client = new AmazonDynamoDBClient(credentials, region);
      Table books = Table.LoadTable(client, "Books");
      var book = await books.GetItemAsync(id);
}
```

### Update an Item
<a name="update-an-item"></a>

To update an item:

```
public async Task UpdateItemAttributesAsync(AWSCredentials credentials, RegionEndpoint region)
{
      var book = new Document();
      book["Id"] = id;
      book["PageCount"] = "200";
      var client = new AmazonDynamoDBClient(credentials, region);
      Table books = Table.LoadTable(client, "Books");
      Document updatedBook = await books.UpdateItemAsync(book);
}
```

To update an item conditionally:

```
public async Task UpdateItemConditionallyAsync(AWSCredentials credentials, RegionEndpoint region) {
      var book = new Document();
      book["Id"] = id;
      book["Price"] = "30";

      // For conditional price update, creating a condition expression.
      Expression expr = new Expression();
      expr.ExpressionStatement = "Price = :val";
      expr.ExpressionAttributeValues[":val"] = 10.00;

      var client = new AmazonDynamoDBClient(credentials, region);
      Table books = Table.LoadTable(client, "Books");

      Document updatedBook = await books.UpdateItemAsync(book);
}
```

### Delete an Item
<a name="delete-an-item"></a>

To delete an item:

```
public async Task DeleteItemAsync(AWSCredentials credentials, RegionEndpoint region)
{
  var client = new AmazonDynamoDBClient(credentials, region);
  Table books = Table.LoadTable(client, "Books");
  await books.DeleteItemAsync(id);
}
```

### Query and Scan
<a name="query-and-scan"></a>

To query and retrieve all books whose author is “Mark Twain”:

```
public async Task QueryAsync(AWSCredentials credentials, RegionEndpoint region) {
  var client = new AmazonDynamoDBClient(credentials, region);
  Table books = Table.LoadTable(client, "Books");
  var search = books.Query(new QueryOperationConfig() {
   IndexName = "Author-Title-index",
   Filter = new QueryFilter("Author", QueryOperator.Equal, "Mark Twain")
  });
  Console.WriteLine("ScanAsync: printing query response");
  var documents = await search.GetRemainingAsync();
  documents.ForEach((d) = > {
   PrintDocument(d);
  });
}
```

The scan example code below returns all books in our table:

```
public async Task ScanAsync(AWSCredentials credentials, RegionEndpoint region) {
      var client = new AmazonDynamoDBClient(credentials, region);
      Table books = Table.LoadTable(client, "Books");
      var search = books.Scan(new ScanOperationConfig() {
              ConsistentRead = true
      });
      Console.WriteLine("ScanAsync: printing scan response");
      var documents = await search.GetRemainingAsync();
      documents.ForEach((d) = > {
              PrintDocument(d);
      });
}
```

# Using the Object Persistence Model
<a name="dynamodb-integration-objectpersistencemodel"></a>

The AWS Mobile SDK for .NET and Xamarin provides an Object Persistence model that enables you to map your client-side classes to a DynamoDB table. Each object instance then maps to an item in the corresponding table. To save your client-side objects to a table, the Object Persistence model provides the DynamoDBContext class, an entry point to DynamoDB. This class provides you a connection to DynamoDB and enables you to access tables, perform various CRUD operations, and execute queries.

The Object Persistence model does not provide an API to create, update, or delete tables. It provides only data operations. To create, update and delete tables, you must use the low-level API. For instructions on how to use the low-level API, see [Using the DynamoDB Service Level APIs](dynamodb-integration-lowlevelapi.md).

## Overview
<a name="overview"></a>

The Object Persistence model provides a set of attributes to map client-side classes to tables, and properties/fields to table attributes. The Object Persistence model supports both the explicit and default mapping between class properties and table attributes.
+  **Explicit mapping**: To map a property to a primary key, you must use the DynamoDBHashKey and DynamoDBRangeKey Object Persistence model attributes. Additionally, for the non-primary key attributes, if a property name in your class and the corresponding table attribute to which you want to map it are not the same, then you must define the mapping by explicitly adding the DynamoDBProperty attribute.
+  **Default mapping** - By default, the Object Persistence model maps the class properties to the attributes with the same name in the table.

You do not have to map every single class property. You identify these properties by adding the DynamoDBIgnore attribute. Saving and retrieving an instance of an object would omit any property marked with this attribute.

## Supported Data Types
<a name="supported-data-types"></a>

The Object Persistence model supports a set of primitive .NET data types, collections, and arbitrary data types. The model supports the following primitive data types.
+ bool
+ byte
+ char
+ DateTime
+ decimal, double, float
+ Int16, Int32, Int64
+ SByte
+ string
+ UInt16, UInt32, UInt64

The Object Persistence model also supports the .NET collection types with the following limitations:
+ Collection type must implement ICollection interface.
+ Collection type must be composed of the supported primitive types. For example, ICollection<string>, ICollection<bool>.
+ Collection type must provide a parameter-less constructor.

For more information on the Object Persistence model, see [.NET Object Persistence Model](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DotNetSDKHighLevel.html).

## Create a DynamoDB Client
<a name="create-a-dynamodb-client"></a>

To create a DynamoDB client:

```
var client = new AmazonDynamoDBClient(credentials,region);
DynamoDBContext context = new DynamoDBContext(client);
```

## CRUD Operations
<a name="crud-operations"></a>

### Save an Object
<a name="save-an-object"></a>

Create an object:

```
[DynamoDBTable("Books")]
public class Book {
  [DynamoDBHashKey] // Hash key.
  public string Id {
    get;
    set;
  }

  [DynamoDBGlobalSecondaryIndexHashKey]
  public string Author {
    get;
    set;
  }

  [DynamoDBGlobalSecondaryIndexRangeKey]
  public string Title {
    get;
    set;
  }
  public string ISBN {
    get;
    set;
  }
  public int Price {
    get;
    set;
  }
  public string PageCount {
    get;
    set;
  }
}

Book myBook = new Book
{
    Id = id,
    Author = "Charles Dickens",
    Title = "Oliver Twist",
    ISBN = "111-1111111001",
    Price = 10,
    PageCount = 300
};
```

Save an object to a DynamoDB table:

```
context.Save(myBook);
```

### Retrieve an Object
<a name="retrieve-an-object"></a>

To retrieve an object:

```
Book retrievedBook = context.Load<Book>(1);
```

### Update an Object
<a name="update-an-object"></a>

To update an object:

```
Book retrievedBook = context.Load<Book>(1);
retrievedBook.ISBN = "111-1111111001";
context.Save(retrievedBook);
```

### Delete an Object
<a name="delete-an-object"></a>

To delete an object:

```
Book retrievedBook = context.Load<Book>(1);
context.Delete(retrievedBook);
```

## Query and Scan
<a name="query-and-scan"></a>

To query and retrieve all books whose author is “Charles Dickens”:

```
public async Task QueryAsync(AWSCredentials credentials, RegionEndpoint region) {
  var client = new AmazonDynamoDBClient(credentials, region);
  DynamoDBContext context = new DynamoDBContext(client);

  var search = context.FromQueryAsync < Book > (new Amazon.DynamoDBv2.DocumentModel.QueryOperationConfig() {
    IndexName = "Author-Title-index",
    Filter = new Amazon.DynamoDBv2.DocumentModel.QueryFilter("Author", Amazon.DynamoDBv2.DocumentModel.QueryOperator.Equal, "Charles Dickens")
  });

  Console.WriteLine("items retrieved");

  var searchResponse = await search.GetRemainingAsync();
  searchResponse.ForEach((s) = > {
    Console.WriteLine(s.ToString());
  });
}
```

The scan example code below returns all books in our table:

```
public async Task ScanAsync(AWSCredentials credentials, RegionEndpoint region) {
  var client = new AmazonDynamoDBClient(credentials, region);
  DynamoDBContext context = new DynamoDBContext(client);

  var search = context.FromScanAsync < Book > (new Amazon.DynamoDBv2.DocumentModel.ScanOperationConfig() {
   ConsistentRead = true
  });

  Console.WriteLine("items retrieved");

  var searchResponse = await search.GetRemainingAsync();
  searchResponse.ForEach((s) = > {
   Console.WriteLine(s.ToString());
  });
}
```

# Using the DynamoDB Service Level APIs
<a name="dynamodb-integration-lowlevelapi"></a>

The Dynamo Service Level APIs allow you to create, update and delete tables. You can also perform typical create, read, update, and delete (CRUD) operations on items in a table using this API.

## Create a DynamoDB Client
<a name="create-a-dynamodb-client"></a>

To create a DynamoDB client:

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient(credentials,region);
```

## CRUD Operations
<a name="crud-operations"></a>

### Save an Item
<a name="save-an-item"></a>

To save an item to a DynamoDB table:

```
// Create a client
AmazonDynamoDBClient client = new AmazonDynamoDBClient(credentials,region);

// Define item attributes
Dictionary<string, AttributeValue> attributes = new Dictionary<string, AttributeValue>();

// Author is hash-key
attributes["Author"] = new AttributeValue { S = "Mark Twain" };
attributes["Title"] = new AttributeValue { S = "The Adventures of Tom Sawyer" };
attributes["PageCount"] = new AttributeValue { N = "275" };
attributes["Price"] = new AttributeValue{N = "10.00"};
attributes["Id"] = new AttributeValue{N="10"};
attributes["ISBN"] = new AttributeValue{S="111-1111111"};

// Create PutItem request
PutItemRequest request = new PutItemRequest
{
    TableName = "Books",
    Item = attributes
};

// Issue PutItem request
var response = await client.PutItemAsync(request);
```

### Retrieve an Item
<a name="retrieve-an-item"></a>

To retrieve an item:

```
// Create a client
AmazonDynamoDBClient client = new AmazonDynamoDBClient(credentials,region);

Dictionary<string, AttributeValue> key = new Dictionary<string, AttributeValue>
{
    { "Id", new AttributeValue { N = "10" } }
};

// Create GetItem request
GetItemRequest request = new GetItemRequest
{
    TableName = "Books",
    Key = key,
};

// Issue request
var result = await client.GetItemAsync(request);

// View response
Console.WriteLine("Item:");
Dictionary<string, AttributeValue> item = result.Item;
foreach (var keyValuePair in item)
{
    Console.WriteLine("Author := {0}", item["Author"]);
    Console.WriteLine("Title := {0}", item["Title"]);
    Console.WriteLine("Price:= {0}", item["Price"]);
    Console.WriteLine("PageCount := {0}", item["PageCount"]);
}
```

### Update an Item
<a name="update-an-item"></a>

To update an item:

```
// Create a client
AmazonDynamoDBClient client = new AmazonDynamoDBClient(credentials,region);

Dictionary<string, AttributeValue> key = new Dictionary<string, AttributeValue>
{
    { "Id", new AttributeValue { N = "10" } }
};

// Define attribute updates
Dictionary<string, AttributeValueUpdate> updates = new Dictionary<string, AttributeValueUpdate>();
// Add a new string to the item's Genres SS attribute
updates["Genres"] = new AttributeValueUpdate()
{
    Action = AttributeAction.ADD,
    Value = new AttributeValue { SS = new List<string> { "Bildungsroman" } }
};

// Create UpdateItem request
UpdateItemRequest request = new UpdateItemRequest
{
    TableName = "Books",
    Key = key,
    AttributeUpdates = updates
};

// Issue request
var response = await client.UpdateItemAsync(request);
```

### Delete an Item
<a name="delete-an-item"></a>

To delete an item:

```
// Create a client
AmazonDynamoDBClient client = new AmazonDynamoDBClient(credentials,region);

Dictionary<string, AttributeValue> key = new Dictionary<string, AttributeValue>
{
  { "Id", new AttributeValue { N = "10" } }
};

// Create DeleteItem request
DeleteItemRequest request = new DeleteItemRequest
{
  TableName = "Books",
  Key = key
};

// Issue request
var response = await client.DeleteItemAsync(request);
```

## Query and Scan
<a name="query-and-scan"></a>

To query and retrieve all books whose author is “Mark Twain”:

```
public void Query(AWSCredentials credentials, RegionEndpoint region) {
  using(var client = new AmazonDynamoDBClient(credentials, region)) {
    var queryResponse = await client.QueryAsync(new QueryRequest() {
      TableName = "Books",
      IndexName = "Author-Title-index",
      KeyConditionExpression = "Author = :v_Id",
      ExpressionAttributeValues = new Dictionary < string, AttributeValue > {
        {
          ":v_Id", new AttributeValue {
            S = "Mark Twain"
          }
        }
      }
    });
    queryResponse.Items.ForEach((i) = > {
      Console.WriteLine(i["Title"].S);
    });

  }
}
```

The scan example code below returns all books in our table:

```
public void Scan(AWSCredentials credentials, RegionEndpoint region) {
      using(var client = new AmazonDynamoDBClient(credentials, region)) {
              var queryResponse = client.Scan(new ScanRequest() {
                      TableName = "Books"
              });
              queryResponse.Items.ForEach((i) = > {
                      Console.WriteLine(i["Title"].S);
              });
      }
}
```