DynamoDB查询是否等效于“ WHERE author IN [..]”?

时间:2018-07-14 20:26:38

标签: node.js amazon-dynamodb

给出以下数据结构;

{
    "author": "USERNAME",
    "caption": "Caption of video",
    "createdAt": 1531260177951,
    "id": "03290200-848d-12e8-a1b5-bb9570f524f1", // Current primary key
    "s3Bucket": "s3-bucket-name",
    "s3Key": "USERNAME/1521260163051.mp4",
    "updatedAt": 1531260177951
}

我正在尝试编写一个查询,这在其他语言(例如SQL或MongoDB)中非常简单;

蒙哥:db.getCollection("Videos").find({author: {$in: ["USER1", "USER2",..]}}).sort({createdAt: 1})

SQL:SELECT * from videos WHERE author IN ('USER1', USER2',...) SORT BY createdAt

如果我在作者字段上添加索引,这些查询通常会很快运行。

我已经在dynamoDb中的author字段上建立了索引,但是看来除了对该字段进行均等检查之外,没有其他方法可以做。 author = :inputAuthor。尝试执行author IN (:author1, :author2)会导致错误Invalid operator used in KeyConditionExpression: IN

DynamoDB对我来说是错误的数据库吗?也许有一些智能索引/查询可以使我的查询快速运行?

有类似的问题,像这样; How to use “IN” statement in FilterExpression using array - dynamodb,但据我所知,它们似乎都依赖于scan,对于大集合而言,这不是最佳选择。

1 个答案:

答案 0 :(得分:3)

如果您看下面的documentation,可能会意识到对于KeyConditionExpressions,只有以下运算符有效:EQ | LE | LT | GE | GT | BEGINS_WITH | BETWEEN

所以,这是一笔交易-如果您希望继续使用dynamodb,并希望对关键条件表达式执行类似IN的操作,则您每次都必须向dynamodb发送各种请求,包括作者分开,然后将它们结合在一起。

类似的东西:

// Considering that this docClient is the instance of aws-sdk configured for dynamodb

const TABLE = 'Videos';

const createParams = (author) => {
    return {
        TableName: TABLE,
        KeyConditionExpression: "author = :author",
        ExpressionAttributeValues: {
            ":author": author
        }
    };
}

const queryPromise = (params) => {
    return new Promise((resolve, reject) => {
        docClient.query(params, function (err, data) {
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        });
    });
}

// The list of authors
const authors = ['Vauxhall', 'Piccadilly', 'Acton', 'Milton', 'Hempsworth'];
const promises = [];

authors.forEach((author) => {
    promises.push(queryPromise(createParams(author)));
});

Promise.all(promises).then(results => {
    // Do your stuff here
}).catch(error => {
    // Handle errors the way you would
});