Вопрос или проблема
У меня есть таблица 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');
}
}
}
Объяснение кода
-
Инъекция модели: Мы используем
@InjectModel
для получения модели, связанной с нашей схемойObjectSchema
. -
Метод
findByValue
:- Мы принимаем строку
value
и используем методscan()
, чтобы пробежаться по всем элементам в таблице. - Метод
where('values').contains(value)
фильтрует результаты, оставляя только те элементы, в которых массивvalues
содержит заданную строкуvalue
. - Важно, чтобы
(value)
был валидным значением, соответствующим типу, указанному в схеме. - Мы используем
try-catch
для обработки возможных ошибок, что позволит отлаживать код и лучше управлять ошибками во время выполнения.
- Мы принимаем строку
Примечания
- Метод
scan()
может быть неэффективным для больших таблиц, поэтому его проверка в пределах разумного объёма данных является хорошей практикой. - Если вы знаете диапазон значений, вы можете рассмотреть возможность использования метода
query()
для оптимизации производительности, но это будет зависеть от проектирования вашей базы данных и индексирования.
Следуя этому подходу, вы должны без проблем получать элементы, соответствующие вашему запросу.