2

我正在使用Dynamoose来简化我在 node.js 应用程序中与 DynamoDB 的交互。我正在尝试使用 Dynamoose 的 Model.query 函数编写一个查询,该函数将使用索引搜索表,但似乎 Dynamoose 不包括处理查询所需的所有信息,我不确定我是什么做错了。

架构如下所示:

const UserSchema = new dynamoose.Schema({
  "user_id": {
    "hashKey": true,
    "type": String
  },
  "email": {
    "type": String,
    "index": {
      "global": true,
      "name": "email-index"
    }
  },
  "first_name": {
    "type": String,
    "index": {
      "global": true,
      "name": "first_name-index"
    }
  },
  "last_name": {
    "type": String,
    "index": {
      "global": true,
      "name": "last_name-index"
    }
  }
)

module.exports = dynamoose.model(config.usersTable, UserSchema)

我希望能够通过电子邮件地址搜索用户,所以我正在编写一个如下所示的查询:

Users.query("email").contains(query.email)
    .using("email-index")
    .all()
    .exec()
    .then( results => {
      res.status(200).json(results)
    }).catch( err => {
      res.status(500).send("Error searching for users: " + err)
    })

我为电子邮件字段定义了一个全局二级索引: 电子邮件索引活动 GSI 电子邮件(字符串) - 全部

当我尝试执行此查询时,我收到以下错误:

Error searching for users: ValidationException: Either the KeyConditions or KeyConditionExpression parameter must be specified in the request.

使用 Dynamoose 调试输出,我可以看到查询最终看起来像这样:

aws:dynamodb:query:request - {
"FilterExpression": "contains (#a0, :v0)",
"ExpressionAttributeNames": {
    "#a0": "email"
},
"ExpressionAttributeValues": {
    ":v0": {
        "S": "mel"
    }
},
"TableName": "user_qa",
"IndexName": "email-index"
}

我注意到发送到 DynamoDB 的实际查询不包含 KeyConditions 或 KeyConditionExpression,如错误消息所示。我做错了什么会阻止正确编写此查询,以便它针对我为此表添加的全局二级索引执行查询?

4

2 回答 2

4

事实证明,like 调用.contains(text)用作过滤器,而不是查询参数。DynamoDB 无法确定索引中的文本是否包含我正在搜索的文本,而无需查看每条记录,这是扫描,而不是查询。所以尝试.contains(text)在这种情况下使用是没有意义的,即使可以像我构建的那样在链中调用它。为了完成这项工作,我最终需要做的是使用.contains(text)过滤器将我的调用转换为表扫描:

Users.scan({ email: { contains: query.email }}).all().exec().then( ... )
于 2020-06-24T20:45:59.753 回答
-1

我对 Dynamoose 不太熟悉,但下面的代码将使用 node.JS 和 DynamoDB 对记录进行更新。请参阅下面的关键参数;根据您收到的错误消息,您似乎错过了这一点。

据我所知,您必须为 UPDATE 请求指定一个键。您可以查看 AWS DynamoDB 文档进行确认。

var params = {
    TableName: table,
    Key: {
        "id": customerID,
    },

    UpdateExpression: "set customer_name= :s, customer_address= :p, customer_phone= :u, end_date = :u",
    ExpressionAttributeValues: {
        ":s": customer_name,
        ":p": customer_address,
        ":u": customer_phone
    },
    ReturnValues: "UPDATED_NEW"
};
    await docClient.update(params).promise();
于 2020-06-24T11:19:15.287 回答