Yandex Cloud
  • Сервисы
  • Решения
  • Почему Yandex Cloud
  • Сообщество
  • Тарифы
  • Документация
  • Связаться с нами
Подключиться
Language / Region
Проект Яндекса
© 2023 ООО «Яндекс.Облако»
Yandex Managed Service for YDB
  • Начало работы
  • Пошаговые инструкции
    • Обзор
    • Управление базами данных через консоль Yandex Cloud
    • Управление базами данных с помощью YC CLI
    • Подключение к БД с помощью YDB CLI
    • Управление таблицами и директориями
    • Чтение и запись данных
    • Мониторинг состояния базы данных
  • Практические руководства
    • Развертывание веб-приложения
    • Разработка Slack-бота
    • Подключение к YDB из функции Yandex Cloud Functions на Python
    • Подключение к базе данных YDB из функции Yandex Cloud Functions на Node.js
    • Конвертация видео в GIF на Python
    • Разработка навыка Алисы и сайта с авторизацией
    • Миграция базы данных из Yandex Managed Service for MySQL с помощью Yandex Data Transfer
  • Концепции
    • Обзор
    • Термины и определения
    • Режимы работы Serverless и Dedicated
    • Таблицы DynamoDB
    • Квоты и лимиты
  • Управление доступом
  • Правила тарификации
    • Обзор
    • Бессерверный режим
      • Правила тарификации для бессерверного режима
      • Стоимость запроса для YQL
      • Стоимость запроса для Document API
      • Стоимость запроса для специальных API
      • Стоимость операций с топиками
    • Режим с выделенными инстансами
  • Document API, совместимый с Amazon DynamoDB
    • Инструменты
      • Настройка инструментов AWS
      • Работа с данными через HTTP-интерфейс
      • Работа с AWS CLI
        • Обзор
        • Создание таблицы
        • Добавление данных в таблицу
        • Чтение данных из таблицы
        • Обновление данных
        • Выборка данных
        • Удаление созданных ресурсов
      • Работа с AWS SDK
        • Обзор
        • Создание таблицы
        • Загрузка данных в таблицу
        • Управление записями в таблице
          • Создание записи
          • Чтение записи
          • Обновление записи
          • Удаление записи
        • Поиск и извлечение данных
        • Удаление таблицы
    • Справочник Document API
      • Все методы
      • Actions
        • BatchGetItem
        • BatchWriteItem
        • CreateTable
        • DeleteItem
        • DeleteTable
        • DescribeTable
        • DescribeTimeToLive
        • GetItem
        • ListTables
        • PutItem
        • Query
        • Scan
        • TransactGetItems
        • TransactWriteItems
        • UpdateItem
        • UpdateTimeToLive
    • Общие ошибки при работе с Document API
  • Справочник API Yandex Cloud для Managed Service for YDB
    • Обзор
    • Аутентификация в API
    • gRPC (англ.)
      • Overview
      • BackupService
      • DatabaseService
      • LocationService
      • ResourcePresetService
      • StorageTypeService
      • OperationService
    • REST (англ.)
      • Overview
      • Backup
        • Overview
        • delete
        • get
        • list
        • listPaths
      • Database
        • Overview
        • backup
        • create
        • delete
        • get
        • list
        • move
        • restore
        • start
        • stop
        • update
      • Location
        • Overview
        • get
        • list
      • ResourcePreset
        • Overview
        • get
        • list
      • StorageType
        • Overview
        • get
        • list
  • Вопросы и ответы
  • Публичные материалы
  1. Document API, совместимый с Amazon DynamoDB
  2. Инструменты
  3. Работа с AWS SDK
  4. Поиск и извлечение данных

Поиск и извлечение данных

Статья создана
Yandex Cloud
  • Поиск по ключу партицирования
  • Поиск по ключам партицирования и сортировки
  • Сканирование

Для поиска данных в таблице используется метод query, в котором нужно передать атрибуты первичного ключа нужной записи. Если ключ составной, то обязательно указывать только ключ партицирования, а ключ сортировки — опционально.

Первичный ключ таблицы Series составной и состоит из следующих атрибутов:

  • series_id — ключ партицирования (тип поля — число);
  • title — ключ сортировки (тип поля — строка).

Чтобы найти все сериалы с ключом партицирования, равным 3, нужно передать это значение в методе query. Также можно ограничить выбор по названию сериала, указав условие для ключа сортировки. Например, вы можете найти сериалы с ключом партицирования, равным 3, которые имеют название, начинающееся с буквы T.

В дополнение к методу query вы можете использовать метод scan для извлечения всех табличных данных. Метод scan считывает каждую запись и возвращает все данные в таблице. С помощью фильтра можно задать критерии для возвращаемых записей, но фильтр применяется только после сканирования всей таблицы.

Поиск по ключу партицирования

Чтобы извлечь данные методом query из таблицы Series:

Java
Python
PHP
Node.js
Ruby
  1. Создайте проект SeriesQuery01:

    mvn -B archetype:generate \
      -DarchetypeGroupId=org.apache.maven.archetypes \
      -DgroupId=com.mycompany.app \
      -DartifactId=SeriesQuery01
    

    В результате выполнения команды в текущем рабочем каталоге будет создан каталог проекта с именем SeriesQuery01, структурой подкаталогов и файлом описания проекта pom.xml.

  2. Перейдите в каталог проекта:

    cd SeriesQuery01
    
  3. Отредактируйте описание проекта в файле pom.xml, например с помощью редактора nano:

    nano pom.xml
    

    Пример файла pom.xml:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.mycompany.app</groupId>
      <artifactId>SeriesQuery01</artifactId>
      <packaging>jar</packaging>
      <version>1.0-SNAPSHOT</version>
      <name>SeriesQuery01</name>
      <url>http://maven.apache.org</url>
      <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-jar-plugin</artifactId>
                  <configuration>
                      <archive>
                          <manifest>
                              <addClasspath>true</addClasspath>
                              <classpathPrefix>lib/</classpathPrefix>
                              <mainClass>com.mycompany.app.SeriesQuery01</mainClass>
                          </manifest>
                          <manifestEntries>
                              <Class-Path>.</Class-Path>
                          </manifestEntries>
                      </archive>
                      <finalName>release/SeriesQuery01</finalName>
                  </configuration>
              </plugin>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-dependency-plugin</artifactId>
                  <executions>
                      <execution>
                          <id>copy-dependencies</id>
                          <phase>prepare-package</phase>
                          <goals>
                              <goal>copy-dependencies</goal>
                          </goals>
                          <configuration>
                              <outputDirectory>${project.build.directory}/release/lib</outputDirectory>
                              <overWriteReleases>false</overWriteReleases>
                              <overWriteSnapshots>false</overWriteSnapshots>
                              <overWriteIfNewer>true</overWriteIfNewer>
                          </configuration>
                      </execution>
                  </executions>
              </plugin>
          </plugins>
      </build>
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.13.1</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>com.amazonaws</groupId>
          <artifactId>aws-java-sdk-dynamodb</artifactId>
          <version>1.11.1012</version>
        </dependency>
      </dependencies>
      <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
      </properties>
    </project>
    

    Посмотрите актуальные версии junit и aws-java-sdk-dynamodb.

  4. В каталоге src/main/java/com/mycompany/app/ создайте файл SeriesQuery01.java, например с помощью редактора nano:

    nano src/main/java/com/mycompany/app/SeriesQuery01.java
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    package com.mycompany.app;
    
    import java.util.HashMap;
    import java.util.Iterator;
    
    import com.amazonaws.client.builder.AwsClientBuilder;
    import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
    import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
    import com.amazonaws.services.dynamodbv2.document.DynamoDB;
    import com.amazonaws.services.dynamodbv2.document.Item;
    import com.amazonaws.services.dynamodbv2.document.ItemCollection;
    import com.amazonaws.services.dynamodbv2.document.QueryOutcome;
    import com.amazonaws.services.dynamodbv2.document.Table;
    import com.amazonaws.services.dynamodbv2.document.spec.QuerySpec;
    
    public class SeriesQuery01 {
    
        public static void main(String[] args) throws Exception {
    
            AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("<Document API эндпоинт>", "ru-central1"))
                .build();
    
            DynamoDB dynamoDB = new DynamoDB(client);
    
            Table table = dynamoDB.getTable("Series");
    
            HashMap<String, Object> valueMap = new HashMap<String, Object>();
            valueMap.put(":sd", 3);
    
            QuerySpec querySpec = new QuerySpec().withKeyConditionExpression("series_id = :sd").withValueMap(valueMap);
    
            ItemCollection<QueryOutcome> items = null;
            Iterator<Item> iterator = null;
            Item item = null;
    
            try {
                System.out.println("Сериалы с id, равным 3");
                items = table.query(querySpec);
    
                iterator = items.iterator();
                while (iterator.hasNext()) {
                    item = iterator.next();
                    System.out.println(item.getNumber("series_id") + ": " + item.getString("title"));
                }
    
            }
            catch (Exception e) {
                  System.err.println("Невозможно выполнить поиск");
                  System.err.println(e.getMessage());
            }
    
        }
    }
    

    Этот код извлекает из таблицы Series все сериалы с ключом партицирования, равным 3.

    Примечание

    valueMap используется для подстановки значений. Это необходимо потому, что нельзя использовать литералы непосредственно в выражениях, в том числе и в KeyConditionExpression. В приведенном коде используется :sd.

    Сначала вы создаете объект querySpec, который описывает параметры запроса, а затем передаете этот объект в метод query.

  5. Соберите проект:

    mvn package
    

    В результате выполнения команды в каталоге target/release/ будет сгенерирован файл SeriesQuery01.jar.

  6. Запустите приложение:

    java -jar target/release/SeriesQuery01.jar
    

    Результат:

    Сериалы с id, равным 3
    3: House of Cards
    3: The Office
    3: True Detective
    
  1. Создайте файл SeriesQuery01.py, например с помощью редактора nano:

    nano SeriesQuery01.py
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    import boto3
    from boto3.dynamodb.conditions import Key
    
    def query_series(series_id):
        ydb_docapi_client = boto3.resource('dynamodb', endpoint_url = "<Document API эндпоинт>")
    
        table = ydb_docapi_client.Table('Series')
        response = table.query(
            KeyConditionExpression = Key('series_id').eq(series_id)
        )
        return response['Items']
    
    if __name__ == '__main__':
        query_id = 3
        print(f"Сериалы с id = {query_id}")
        series = query_series(query_id)
        for serie in series:
            print(serie['series_id'], ":", serie['title'])
    

    Этот код извлекает из таблицы Series все сериалы с ключом партицирования, равным 3.

    SDK Boto 3 создает параметр ConditionExpression за вас, когда вы используете функции Key и Attr, импортированные из boto3.dynamodb.conditions. Вы также можете указать значение параметра ConditionExpression в виде строки.

  2. Запустите программу:

    python SeriesQuery01.py
    

    Результат:

    Сериалы с id = 3
    3 : House of Cards
    3 : The Office
    3 : True Detective
    
  1. Создайте файл SeriesQuery01.php, например с помощью редактора nano:

    nano SeriesQuery01.php
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    <?php
    
    require 'vendor/autoload.php';
    
    date_default_timezone_set('UTC');
    
    use Aws\DynamoDb\Exception\DynamoDbException;
    use Aws\DynamoDb\Marshaler;
    
    $sdk = new Aws\Sdk([
        'endpoint' => '<Document API эндпоинт>',
        'region'   => 'ru-central1',
        'version'  => 'latest'
    ]);
    
    $dynamodb = $sdk->createDynamoDb();
    $marshaler = new Marshaler();
    
    $tableName = 'Series';
    
    $eav = $marshaler->marshalJson('
        {
            ":sd": 3
        }
    ');
    
    $params = [
        'TableName' => $tableName,
        'KeyConditionExpression' => 'series_id = :sd',
        'ExpressionAttributeValues'=> $eav
    ];
    
    echo "Сериалы с id, равным 3\n";
    
    try {
        $result = $dynamodb->query($params);
    
        echo "Поиск выполнен.\n";
    
        foreach ($result['Items'] as $movie) {
            echo $marshaler->unmarshalValue($movie['series_id']) . ': ' .
                $marshaler->unmarshalValue($movie['title']) . "\n";
        }
    
    } catch (DynamoDbException $e) {
        echo "Невозможно выполнить поиск:\n";
        echo $e->getMessage() . "\n";
    }
    
    ?>
    

    Этот код извлекает из таблицы Series все сериалы с ключом партицирования, равным 3.

    Примечание

    ExpressionAttributeValues используется для подстановки значений. Это необходимо потому, что нельзя использовать литералы непосредственно в выражениях, в том числе и в KeyConditionExpression. В приведенном коде используется :sd.

  2. Запустите программу:

    php SeriesQuery01.php
    

    Результат:

    Сериалы с id, равным 3
    Поиск выполнен.
    3: House of Cards
    3: The Office
    3: True Detective
    
  1. Создайте файл SeriesQuery01.js, например с помощью редактора nano:

    nano SeriesQuery01.js
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    const AWS = require("@aws-sdk/client-dynamodb");
    const { marshall } = require("@aws-sdk/util-dynamodb");
    
    // Credentials should be defined via environment variables AWS_SECRET_ACCESS_KEY and AWS_ACCESS_KEY_ID
    const dynamodb = new AWS.DynamoDBClient({
        region: "ru-central1",
        endpoint: "<Document API эндпоинт>",
    });
    
    console.log("Поиск фильмов с ключом партицирования, равным 3.");
    
    const params = {
        TableName : "Series",
        KeyConditionExpression: "series_id = :val",
        ExpressionAttributeValues: marshall({
            ":val": 3
        }),
    };
    
    dynamodb.send(new AWS.QueryCommand(params))
        .then(data => {
            console.log("Запрос успешно выполнен:");
            data.Items.forEach(function(item) {
                console.log(" -", item.series_id + ": " + item.title);
            });
        })
        .catch(err => {
            console.error("Не удалось выполнить запрос. Ошибка:", JSON.stringify(err, null, 2));
        });
    

    Этот код извлекает из таблицы Series все сериалы с ключом партицирования, равным 3.

  2. Запустите программу:

    node SeriesQuery01.js
    

    Результат:

    Поиск фильмов с ключом партицирования, равным 3.
    Запрос успешно выполнен:
    - 3: House of Cards
    - 3: The Office
    - 3: True Detective
    
  1. Создайте файл SeriesQuery01.rb, например с помощью редактора nano:

    nano SeriesQuery01.rb
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    require 'aws-sdk-dynamodb'
    
    def query_for_items_from_table(dynamodb_client, query_condition)
      result = dynamodb_client.query(query_condition)
      if result.items.count.zero?
        puts 'Результатов не найдено.'
      else
        puts "Найдено #{result.items.count} записей:"
        result.items.each do |movie|
          puts "#{movie['title']} (#{movie['series_id'].to_i})"
        end
      end
    rescue StandardError => e
      puts "Ошибка получения элементов из таблицы: #{e.message}"
    end
    
    def run_me
      region = 'ru-central1'
      table_name = 'Series'
      series_id = 3
    
      Aws.config.update(
        endpoint: '<Document API эндпоинт>',
        region: region
      )
    
      dynamodb_client = Aws::DynamoDB::Client.new
      query_condition = {
        table_name: table_name,
        key_condition_expression: 'series_id = :val',
        expression_attribute_values: {
          ':val' => 3
        }
      }
    
      puts "Поиск фильмов с ключом партицирования, равным '#{series_id}' в таблице '#{table_name}'..."
    
      query_for_items_from_table(dynamodb_client, query_condition)
    end
    
    run_me if $PROGRAM_NAME == __FILE__
    

    Этот код извлекает из таблицы Series все сериалы с ключом партицирования, равным 3.

  2. Запустите программу:

    ruby SeriesQuery01.rb
    

    Результат:

    Поиск фильмов с ключом партицирования, равным '3' в таблице 'Series'...
    Найдено 3 записей:
    House of Cards (3)
    The Office (3)
    True Detective (3)
    

Поиск по ключам партицирования и сортировки

Чтобы найти в таблице Series сериалы с ключом партицирования, равным 3, и названием на букву T:

Java
Python
PHP
Node.js
Ruby
  1. Создайте проект SeriesQuery02:

    mvn -B archetype:generate \
      -DarchetypeGroupId=org.apache.maven.archetypes \
      -DgroupId=com.mycompany.app \
      -DartifactId=SeriesQuery02
    

    В результате выполнения команды в текущем рабочем каталоге будет создан каталог проекта с именем SeriesQuery02, структурой подкаталогов и файлом описания проекта pom.xml.

  2. Перейдите в каталог проекта:

    cd SeriesQuery02
    
  3. Отредактируйте описание проекта в файле pom.xml, например с помощью редактора nano:

    nano pom.xml
    

    Пример файла pom.xml:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.mycompany.app</groupId>
      <artifactId>SeriesQuery02</artifactId>
      <packaging>jar</packaging>
      <version>1.0-SNAPSHOT</version>
      <name>SeriesQuery02</name>
      <url>http://maven.apache.org</url>
      <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-jar-plugin</artifactId>
                  <configuration>
                      <archive>
                          <manifest>
                              <addClasspath>true</addClasspath>
                              <classpathPrefix>lib/</classpathPrefix>
                              <mainClass>com.mycompany.app.SeriesQuery02</mainClass>
                          </manifest>
                          <manifestEntries>
                              <Class-Path>.</Class-Path>
                          </manifestEntries>
                      </archive>
                      <finalName>release/SeriesQuery02</finalName>
                  </configuration>
              </plugin>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-dependency-plugin</artifactId>
                  <executions>
                      <execution>
                          <id>copy-dependencies</id>
                          <phase>prepare-package</phase>
                          <goals>
                              <goal>copy-dependencies</goal>
                          </goals>
                          <configuration>
                              <outputDirectory>${project.build.directory}/release/lib</outputDirectory>
                              <overWriteReleases>false</overWriteReleases>
                              <overWriteSnapshots>false</overWriteSnapshots>
                              <overWriteIfNewer>true</overWriteIfNewer>
                          </configuration>
                      </execution>
                  </executions>
              </plugin>
          </plugins>
      </build>
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.13.1</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>com.amazonaws</groupId>
          <artifactId>aws-java-sdk-dynamodb</artifactId>
          <version>1.11.1012</version>
        </dependency>
      </dependencies>
      <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
      </properties>
    </project>
    

    Посмотрите актуальные версии junit и aws-java-sdk-dynamodb.

  4. В каталоге src/main/java/com/mycompany/app/ создайте файл SeriesQuery02.java, например с помощью редактора nano:

    nano src/main/java/com/mycompany/app/SeriesQuery02.java
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    package com.mycompany.app;
    
    import java.util.HashMap;
    import java.util.Iterator;
    
    import com.amazonaws.client.builder.AwsClientBuilder;
    import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
    import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
    import com.amazonaws.services.dynamodbv2.document.DynamoDB;
    import com.amazonaws.services.dynamodbv2.document.Item;
    import com.amazonaws.services.dynamodbv2.document.ItemCollection;
    import com.amazonaws.services.dynamodbv2.document.QueryOutcome;
    import com.amazonaws.services.dynamodbv2.document.Table;
    import com.amazonaws.services.dynamodbv2.document.spec.QuerySpec;
    
    public class SeriesQuery02 {
    
        public static void main(String[] args) throws Exception {
    
            AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("<Document API эндпоинт>", "ru-central1"))
                .build();
    
            DynamoDB dynamoDB = new DynamoDB(client);
    
            Table table = dynamoDB.getTable("Series");
    
            ItemCollection<QueryOutcome> items = null;
            Iterator<Item> iterator = null;
            Item item = null;
    
            HashMap<String, Object> valueMap = new HashMap<String, Object>();
            valueMap.put(":sd", 3);
            valueMap.put(":letter", "T");
    
            QuerySpec querySpec = new QuerySpec().withProjectionExpression("series_id, title")
                .withKeyConditionExpression("series_id = :sd and begins_with(title, :letter)")
                .withValueMap(valueMap);
    
            try {
                System.out.println("Сериалы с id, равным 3 и названием на букву T:");
                items = table.query(querySpec);
    
                iterator = items.iterator();
                while (iterator.hasNext()) {
                    item = iterator.next();
                    System.out.println(item.getNumber("series_id") + ": " + item.getString("title"));
                }
    
            }
            catch (Exception e) {
                System.err.println("Невозможно выполнить поиск");
                System.err.println(e.getMessage());
            }
    
        }
    }
    
  5. Соберите проект:

    mvn package
    

    В результате выполнения команды в каталоге target/release/ будет сгенерирован файл SeriesQuery02.jar.

  6. Запустите приложение:

    java -jar target/release/SeriesQuery02.jar
    

    Результат:

    Сериалы с id, равным 3 и названием на букву T:
    3: The Office
    3: True Detective
    
  1. Создайте файл SeriesQuery02.py, например с помощью редактора nano:

    nano SeriesQuery02.py
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    from pprint import pprint
    import boto3
    from boto3.dynamodb.conditions import Key
    
    def query_and_project_series(series_id, title_range):
        ydb_docapi_client = boto3.resource('dynamodb', endpoint_url = "<Document API эндпоинт>")
    
        table = ydb_docapi_client.Table('Series')
        
        response = table.query(
            ProjectionExpression = "series_id, title, info.release_date",
            KeyConditionExpression = Key('series_id').eq(series_id) & Key('title').begins_with(title_range)
        )
        return response['Items']
    
    if __name__ == '__main__':
        query_id = 3
        query_range = 'T'
        print(f"Сериалы с id = {query_id} и названием на букву "
              f"{query_range}")
        series = query_and_project_series(query_id, query_range)
        for serie in series:
            print(f"\n{serie['series_id']} : {serie['title']}")
            pprint(serie['info'])
    
  2. Запустите программу:

    python SeriesQuery02.py
    

    Результат:

    Сериалы с id = 3 и названием на букву Т
    3 : The Office
    3 : True Detective
    
  1. Создайте файл SeriesQuery02.php, например с помощью редактора nano:

    nano SeriesQuery02.php
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    <?php
    
    require 'vendor/autoload.php';
    
    date_default_timezone_set('UTC');
    
    use Aws\DynamoDb\Exception\DynamoDbException;
    use Aws\DynamoDb\Marshaler;
    
    $sdk = new Aws\Sdk([
        'endpoint' => '<Document API эндпоинт>',
        'region'   => 'ru-central1',
        'version'  => 'latest'
    ]);
    
    $dynamodb = $sdk->createDynamoDb();
    $marshaler = new Marshaler();
    
    $tableName = 'Series';
    
    $eav = $marshaler->marshalJson('
        {
            ":sd": 3,
            ":letter": "T"
        }
    ');
    
    $params = [
        'TableName' => $tableName,
        'ProjectionExpression' => 'series_id, title',
        'KeyConditionExpression' =>
            'series_id = :sd and begins_with(title, :letter)',
        'ExpressionAttributeValues'=> $eav
    ];
    
    echo "Сериалы с id, равным 3 и названием на букву T:\n";
    
    try {
        $result = $dynamodb->query($params);
    
        echo "Поиск выполнен.\n";
    
        foreach ($result['Items'] as $i) {
            $movie = $marshaler->unmarshalItem($i);
            print $movie['series_id'] . ': ' . $movie['title'] . "\n";
        }
    
    } catch (DynamoDbException $e) {
        echo "Невозможно выполнить поиск:\n";
        echo $e->getMessage() . "\n";
    }
    
    ?>
    
  2. Запустите программу:

    php SeriesQuery02.php
    

    Результат:

    Сериалы с id, равным 3 и названием на букву T:
    Поиск выполнен.
    3: The Office
    3: True Detective
    
  1. Создайте файл SeriesQuery02.js, например с помощью редактора nano:

    nano SeriesQuery02.js
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    var AWS = require("aws-sdk");
    
    AWS.config.update({
      region: "ru-central1",
      endpoint: "<Document API эндпоинт>"
    });
    
    var docClient = new AWS.DynamoDB.DocumentClient();
    
    console.log("Сериалы с id = 3 и названием на букву Т:");
    
    var params = {
        TableName : "Series",
        ProjectionExpression: "#series_id, title",
        KeyConditionExpression: "#series_id = :series_id and begins_with(title,:letter)",
        ExpressionAttributeNames:{
            "#series_id": "series_id",
            "#letter": "letter"
        },
        ExpressionAttributeValues: {
            ":series_id": 3,
            ":letter": 'T'
        }
    };
    
    docClient.query(params, function(err, data) {
        if (err) {
            console.log("Не удалось выполнить запрос. Ошибка:", JSON.stringify(err, null, 2));
        } else {
            console.log("Запрос успешно выполнен:");
            data.Items.forEach(function(item) {
                console.log(" -", item.series_id + ": " + item.title);
            });
        }
    });
    
  2. Запустите программу:

    node SeriesQuery02.js
    

    Результат:

    Сериалы с id = 3 и названием на букву Т:
    Запрос успешно выполнен:
    - 3: The Office
    - 3: True Detective
    
  1. Создайте файл SeriesQuery02.rb, например с помощью редактора nano:

    nano SeriesQuery02.rb
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    require 'aws-sdk-dynamodb'
    
    def query_for_items_from_table(dynamodb_client, query_condition)
      result = dynamodb_client.query(query_condition)
      if result.items.count.zero?
        puts 'Результатов не найдено.'
      else
        puts "Найдено #{result.items.count} записей:"
        result.items.each do |movie|
          puts "#{movie['title']} (#{movie['series_id'].to_i}) "      
        end
      end
    rescue StandardError => e
      puts "Ошибка получения элементов из таблицы: #{e.message}"
    end
    
    def run_me
      region = 'ru-central1'
      table_name = 'Series'
      series_id = 3
    
      Aws.config.update(
        endpoint: '<Document API эндпоинт>',
        region: region
      )
    
      dynamodb_client = Aws::DynamoDB::Client.new
      query_condition = {
        table_name: table_name,
        key_condition_expression: 'series_id = :val and begins_with(title,:letter)',
        expression_attribute_values: {
          ':val' => 3,
          ':letter' => 'T'
        }
      }
    
      puts "Поиск в таблице '#{table_name}' сериалов с id = '#{series_id}' и названием на букву Т"              
    
      query_for_items_from_table(dynamodb_client, query_condition)
    end
    
    run_me if $PROGRAM_NAME == __FILE__
    
  2. Запустите программу:

    ruby SeriesQuery02.rb
    

    Результат:

    Поиск в таблице 'Series' сериалов с id = '3' и названием на букву Т
    Найдено 2 записей:
    The Office (3) 
    True Detective (3) 
    

Сканирование

Чтобы извлечь данные методом scan из таблицы Series:

Java
Python
PHP
Node.js
Ruby
  1. Создайте проект SeriesScan:

    mvn -B archetype:generate \
      -DarchetypeGroupId=org.apache.maven.archetypes \
      -DgroupId=com.mycompany.app \
      -DartifactId=SeriesScan
    

    В результате выполнения команды в текущем рабочем каталоге будет создан каталог проекта с именем SeriesScan, структурой подкаталогов и файлом описания проекта pom.xml.

  2. Перейдите в каталог проекта:

    cd SeriesScan
    
  3. Отредактируйте описание проекта в файле pom.xml, например с помощью редактора nano:

    nano pom.xml
    

    Пример файла pom.xml:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.mycompany.app</groupId>
      <artifactId>SeriesScan</artifactId>
      <packaging>jar</packaging>
      <version>1.0-SNAPSHOT</version>
      <name>SeriesScan</name>
      <url>http://maven.apache.org</url>
      <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-jar-plugin</artifactId>
                  <configuration>
                      <archive>
                          <manifest>
                              <addClasspath>true</addClasspath>
                              <classpathPrefix>lib/</classpathPrefix>
                              <mainClass>com.mycompany.app.SeriesScan</mainClass>
                          </manifest>
                          <manifestEntries>
                              <Class-Path>.</Class-Path>
                          </manifestEntries>
                      </archive>
                      <finalName>release/SeriesScan</finalName>
                  </configuration>
              </plugin>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-dependency-plugin</artifactId>
                  <executions>
                      <execution>
                          <id>copy-dependencies</id>
                          <phase>prepare-package</phase>
                          <goals>
                              <goal>copy-dependencies</goal>
                          </goals>
                          <configuration>
                              <outputDirectory>${project.build.directory}/release/lib</outputDirectory>
                              <overWriteReleases>false</overWriteReleases>
                              <overWriteSnapshots>false</overWriteSnapshots>
                              <overWriteIfNewer>true</overWriteIfNewer>
                          </configuration>
                      </execution>
                  </executions>
              </plugin>
          </plugins>
      </build>
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.13.1</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>com.amazonaws</groupId>
          <artifactId>aws-java-sdk-dynamodb</artifactId>
          <version>1.11.1012</version>
        </dependency>
      </dependencies>
      <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
      </properties>
    </project>
    

    Посмотрите актуальные версии junit и aws-java-sdk-dynamodb.

  4. В каталоге src/main/java/com/mycompany/app/ создайте файл SeriesScan.java, например с помощью редактора nano:

    nano src/main/java/com/mycompany/app/SeriesScan.java
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    package com.mycompany.app;
    
    import java.util.Iterator;
    
    import com.amazonaws.client.builder.AwsClientBuilder;
    import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
    import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
    import com.amazonaws.services.dynamodbv2.document.DynamoDB;
    import com.amazonaws.services.dynamodbv2.document.Item;
    import com.amazonaws.services.dynamodbv2.document.ItemCollection;
    import com.amazonaws.services.dynamodbv2.document.ScanOutcome;
    import com.amazonaws.services.dynamodbv2.document.Table;
    import com.amazonaws.services.dynamodbv2.document.spec.ScanSpec;
    import com.amazonaws.services.dynamodbv2.document.utils.NameMap;
    import com.amazonaws.services.dynamodbv2.document.utils.ValueMap;
    
    public class SeriesScan {
    
        public static void main(String[] args) throws Exception {
    
            AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("<Document API эндпоинт>", "ru-central1"))
                .build();
    
            DynamoDB dynamoDB = new DynamoDB(client);
    
            Table table = dynamoDB.getTable("Series");
    
            ScanSpec scanSpec = new ScanSpec().withProjectionExpression("series_id, title, info.release_date")
                .withFilterExpression("series_id between :start_sd and :end_sd")
                .withValueMap(new ValueMap().withNumber(":start_sd", 1).withNumber(":end_sd", 3));
    
            try {
                ItemCollection<ScanOutcome> items = table.scan(scanSpec);
    
                Iterator<Item> iter = items.iterator();
                while (iter.hasNext()) {
                    Item item = iter.next();
                    System.out.println(item.toString());
                }
            }
            catch (Exception e) {
                System.err.println("Невозможно выполнить сканирование");
                System.err.println(e.getMessage());
            }
    
        }
    }
    

    Приведенный код сканирует таблицу Series и выводит сериалы с атрибутом series_id от 1 до 3. Все остальные элементы отбрасываются.

  5. Соберите проект:

    mvn package
    

    В результате выполнения команды в каталоге target/release/ будет сгенерирован файл SeriesScan.jar.

  6. Запустите приложение:

    java -jar target/release/SeriesScan.jar
    

    Результат:

    { Item: {title=House of Cards, series_id=3, info={release_date=2013-02-01T00:00:00Z}} }
    { Item: {title=The Office, series_id=3, info={release_date=2005-03-24T00:00:00Z}} }
    { Item: {title=True Detective, series_id=3, info={release_date=2014-01-12T00:00:00Z}} }
    { Item: {title=IT Crowd, series_id=1, info={release_date=2006-02-03T00:00:00Z}} }
    { Item: {title=Silicon Valley, series_id=2, info={release_date=2014-04-06T00:00:00Z}} }
    
  1. Создайте файл SeriesScan.py, например с помощью редактора nano:

    nano SeriesScan.py
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    from pprint import pprint
    import boto3
    from boto3.dynamodb.conditions import Key
    
    def scan_series(id_range, display_series):
        ydb_docapi_client = boto3.resource('dynamodb', endpoint_url = "<Document API эндпоинт>")
    
        table = ydb_docapi_client.Table('Series')
        scan_kwargs = {
            'FilterExpression': Key('series_id').between(*id_range),
            'ProjectionExpression': "series_id, title, info.release_date"
        }
    
        done = False
        start_key = None
        while not done:
            if start_key:
                scan_kwargs['ExclusiveStartKey'] = start_key
            response = table.scan(**scan_kwargs)
            display_series(response.get('Items', []))
            start_key = response.get('LastEvaluatedKey', None)
            done = start_key is None
    
    if __name__ == '__main__':
        def print_series(series):
            for serie in series:
                print(f"\n{serie['series_id']} : {serie['title']}")
                pprint(serie['info'])
    
        query_range = (1, 3)
        print(f"Поиск сериалов с id, равным от {query_range[0]} до {query_range[1]}...")
        scan_series(query_range, print_series)
    

    Приведенный код сканирует таблицу Series и выводит сериалы с атрибутом series_id от 1 до 3. Все остальные элементы отбрасываются.

    Для фильтрации найденных данных вы можете указать необязательный параметр FilterExpression, в котором указать условия отбора.

    Метод scan при каждом вызове возвращает подмножество записей, называемое страницей. Затем значение LastEvaluatedKey в ответе передается методу scan через параметр ExclusiveStartKey. Когда возвращается последняя страница, значение LastEvaluatedKey не включается в ответ.

  2. Запустите программу:

    python SeriesScan.py
    

    Результат:

    Поиск сериалов с id, равным от 1 до 3...
    
    3 : House of Cards
    {'release_date': '2013-02-01'}
    
    3 : The Office
    {'release_date': '2005-03-24'}
    
    3 : True Detective
    {'release_date': '2014-01-12'}
    
    1 : IT Crowd
    {'release_date': '2006-02-03'}
    
    2 : Silicon Valley
    {'release_date': '2014-04-06'}
    
  1. Создайте файл SeriesScan.php, например с помощью редактора nano:

    nano SeriesScan.php
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    <?php
    
    require 'vendor/autoload.php';
    
    date_default_timezone_set('UTC');
    
    use Aws\DynamoDb\Exception\DynamoDbException;
    use Aws\DynamoDb\Marshaler;
    
    $sdk = new Aws\Sdk([
        'endpoint' => '<Document API эндпоинт>',
        'region'   => 'ru-central1',
        'version'  => 'latest'
    ]);
    
    $dynamodb = $sdk->createDynamoDb();
    
    $marshaler = new Marshaler();
    
    //Expression attribute values
    $eav = $marshaler->marshalJson('
        {
            ":start_sd": 1,
            ":end_sd": 3
        }
    ');
    
    $params = [
        'TableName' => 'Series',
        'ProjectionExpression' => 'series_id, title',
        'FilterExpression' => 'series_id between :start_sd and :end_sd',
        'ExpressionAttributeValues'=> $eav
    ];
    
    echo "Сканирование таблицы Series.\n";
    
    try {
        while (true) {
            $result = $dynamodb->scan($params);
    
            foreach ($result['Items'] as $i) {
                $movie = $marshaler->unmarshalItem($i);
                echo $movie['series_id'] . ': ' . $movie['title'] . "\n";
            }
    
            if (isset($result['LastEvaluatedKey'])) {
                $params['ExclusiveStartKey'] = $result['LastEvaluatedKey'];
            } else {
                break;
            }
        }
    
    } catch (DynamoDbException $e) {
        echo "Невозможно выполнить сканирование:\n";
        echo $e->getMessage() . "\n";
    }
    
    ?>
    

    Приведенный код сканирует таблицу Series и выводит сериалы с атрибутом series_id от 1 до 3. Все остальные элементы отбрасываются.

  2. Запустите программу:

    php SeriesScan.php
    

    Результат:

    Сканирование таблицы Series.
    3: House of Cards
    3: The Office
    3: True Detective
    1: IT Crowd
    2: Silicon Valley
    
  1. Создайте файл SeriesScan.js, например с помощью редактора nano:

    nano SeriesScan.js
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    var AWS = require("aws-sdk");
    
    AWS.config.update({
      region: "ru-central1",
      endpoint: "<Document API эндпоинт>"
    });
    
    var docClient = new AWS.DynamoDB.DocumentClient();
    
    var params = {
        TableName: "Series",
        ProjectionExpression: "#sid, title, info.rating",
        FilterExpression: "#sid between :start_id and :end_id",
        ExpressionAttributeNames: {
            "#sid": "series_id",
        },
        ExpressionAttributeValues: {
              ":start_id": 1,
              ":end_id": 3
        }
    };
    
    console.log("Сканирование таблицы Series");
    docClient.scan(params, onScan);
    
    function onScan(err, data) {
        if (err) {
            console.error("Не удалось сканировать таблицу. Ошибка JSON:", JSON.stringify(err, null, 2));
        } else {
            console.log("Сканирование успешно.");
            data.Items.forEach(function(series) {
                console.log(
                    series.series_id + ": ",
                    series.title);
            });
    
            if (typeof data.LastEvaluatedKey != "undefined") {
                console.log("Сканирую далее...");
                params.ExclusiveStartKey = data.LastEvaluatedKey;
                docClient.scan(params, onScan);
            }
        }
    }
    

    Приведенный код сканирует таблицу Series и выводит сериалы с атрибутом series_id от 1 до 3. Все остальные элементы отбрасываются.

  2. Запустите программу:

    node SeriesScan.js
    

    Результат:

    Сканирование таблицы Series
    Сканирование успешно.
    3:  House of Cards
    3:  The Office
    3:  True Detective
    1:  IT Crowd
    2:  Silicon Valley
    Сканирую далее...
    Сканирование успешно.
    
  1. Создайте файл SeriesScan.rb, например с помощью редактора nano:

    nano SeriesScan.rb
    

    Скопируйте в созданный файл следующий код:

    Важно

    Вместо <Document API эндпоинт> укажите подготовленное ранее значение.

    require 'aws-sdk-dynamodb'
    
    def scan_for_items_from_table(dynamodb_client, scan_condition)
      loop do
        result = dynamodb_client.scan(scan_condition)
    
        if result.items.count.zero?
          puts 'Подходящих сериалов не найдено (пока)...'
        else
          puts "Найдено #{result.items.count} подходящих сериалов (пока):"
          result.items.each do |movie|
            puts "#{movie["title"]} (#{movie["series_id"].to_i}), " \
              "Rating: #{movie["info"]["rating"].to_f}"
          end
        end
    
        break if result.last_evaluated_key.nil?
    
        puts "Продолжается поиск сериалов..."
        scan_condition[:exclusive_start_key] = result.last_evaluated_key
      end
      puts 'Поиск завершен.'
    rescue StandardError => e
      puts "Ошибка сканирования: #{e.message}"
    end
    
    def run_me
      region = 'ru-central1'
      table_name = 'Series'
      start_id = 1
      end_id = 3
    
      Aws.config.update(
        endpoint: '<Document API эндпоинт>',
        region: region
      )
    
      dynamodb_client = Aws::DynamoDB::Client.new
    
      scan_condition = {
        table_name: table_name,
        projection_expression: '#series_id, title, info.rating',
        filter_expression: '#series_id between :start_id and :end_id',
        expression_attribute_names: { '#series_id' => 'series_id' },
        expression_attribute_values: {
          ':start_id' => start_id,
          ':end_id' => end_id
        }
      }
    
      puts "Поиск сериалов в таблице '#{table_name}' с id в диапазон от #{start_id} до #{end_id}..."
    
      scan_for_items_from_table(dynamodb_client, scan_condition)  
    end
    
    run_me if $PROGRAM_NAME == __FILE__
    

    Приведенный код сканирует таблицу Series и выводит сериалы с атрибутом series_id от 1 до 3. Все остальные элементы отбрасываются.

  2. Запустите программу:

    ruby SeriesScan.rb
    

    Результат:

    Поиск сериалов в таблице 'Series' с id в диапазон от 1 до 3...
    Найдено 5 подходящих сериалов (пока):
    House of Cards (3), Rating: 0.0
    The Office (3), Rating: 0.0
    True Detective (3), Rating: 0.0
    IT Crowd (1), Rating: 0.0
    Silicon Valley (2), Rating: 0.0
    Продолжается поиск сериалов...
    Подходящих сериалов не найдено (пока)...
    Поиск завершен.
    

Была ли статья полезна?

Language / Region
Проект Яндекса
© 2023 ООО «Яндекс.Облако»
В этой статье:
  • Поиск по ключу партицирования
  • Поиск по ключам партицирования и сортировки
  • Сканирование