【问题标题】:How do I query an index properly with Dynamoose如何使用 Dynamoose 正确查询索引
【发布时间】:2020-06-25 04:45:59
【问题描述】:

我正在使用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)
    })

我为电子邮件字段定义了一个全局二级索引:

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

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,如错误消息所示。我做错了什么导致无法正确写入此查询,从而导致它针对我为此表添加的全局二级索引执行查询?

【问题讨论】:

    标签: javascript node.js amazon-dynamodb dynamoose


    【解决方案1】:

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

    Users.scan({ email: { contains: query.email }}).all().exec().then( ... )
    

    【讨论】:

    • 没错。索引只是记录的排序列表。因此,有效使用它们的唯一方法是使用处理该排序的查询(=、
    【解决方案2】:

    我对 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();
    

    【讨论】:

      猜你喜欢
      • 2018-06-21
      • 2017-11-14
      • 2013-12-02
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多