dynamoose/nestjs запросы с значением в массиве

Вопрос или проблема

У меня есть таблица DynamoDB со следующим схемой:

import { Schema } from "dynamoose/dist/Schema";

export const ObjectSchema = new Schema ({
  id: {
    type: String,
    hashKey: true,
  },
  values: {
    type: Array,
    schema: [String],
  }
});

Я хочу выбрать все элементы, где массив values содержит конкретную строку.

Я пробовал следующие подходы:

.scan().where('values').contains(value) 

и

.scan('values').contains(value)

Однако оба раза результатом является ошибка:
TypeError: node.forEach is not a function

Вот метод, который я использую:

  async findByValue(
    value: string,
  ): Promise<ExampleObject[]> {
    return await this.objectModel
      .scan('values')
      .contains(value)
      .exec();

Существует ли способ запроса всех элементов с конкретным value в массиве values, не извлекая все элементы на клиенте и не фильтруя их вручную?

Ответ или решение

Ваша задача заключается в том, чтобы выбрать все элементы из таблицы DynamoDB, где массив values содержит определённое значение. Использование метода .scan() с условием .contains() может вызвать проблемы, если неправильно сформулировать запрос.

Для корректного выполнения запроса с использованием библиотеки Dynamoose в NestJS, вам нужно обратиться к методу scan() и использовать метод where() перед тем, как указать условие. Рассмотрим ваш метод подробнее и предложим рабочий пример.

Полный пример метода

import { Injectable } from '@nestjs/common';
import { InjectModel } from 'nestjs-dynamoose';
import { Model } from 'dynamoose/dist/Model';
import { ExampleObject } from './example-object.interface'; // Замените на ваш интерфейс
import { ObjectSchema } from './object.schema'; // Путь к вашему объекту схемы

@Injectable()
export class ObjectService {
  constructor(
    @InjectModel(ObjectSchema) private readonly objectModel: Model<ExampleObject>
  ) {}

  async findByValue(value: string): Promise<ExampleObject[]> {
    try {
      return await this.objectModel
        .scan()
        .where('values').contains(value)
        .exec();
    } catch (error) {
      console.error('Error while retrieving items:', error);
      throw new Error('Could not retrieve items');
    }
  }
}

Объяснение кода

  1. Инъекция модели: Мы используем @InjectModel для получения модели, связанной с нашей схемой ObjectSchema.

  2. Метод findByValue:

    • Мы принимаем строку value и используем метод scan(), чтобы пробежаться по всем элементам в таблице.
    • Метод where('values').contains(value) фильтрует результаты, оставляя только те элементы, в которых массив values содержит заданную строку value.
    • Важно, чтобы (value) был валидным значением, соответствующим типу, указанному в схеме.
    • Мы используем try-catch для обработки возможных ошибок, что позволит отлаживать код и лучше управлять ошибками во время выполнения.

Примечания

  • Метод scan() может быть неэффективным для больших таблиц, поэтому его проверка в пределах разумного объёма данных является хорошей практикой.
  • Если вы знаете диапазон значений, вы можете рассмотреть возможность использования метода query() для оптимизации производительности, но это будет зависеть от проектирования вашей базы данных и индексирования.

Следуя этому подходу, вы должны без проблем получать элементы, соответствующие вашему запросу.

Оцените материал
Добавить комментарий

Капча загружается...