使用 beginsWith 通过 dynamoose .get 在排序键中搜索

Use beginsWith to search in sort key using dynamoose .get

我开始在这里学习 Dynamodb,目前正尝试在我的 table 上进行搜索,其中 PK 是分区键,SK 是范围键。 PK 包含电子邮件地址,而 SK 包含 AB_STATEBC_STATEMY_STATE 等值。所以我想在值以 MY_ 开头的 SK 中搜索,但我不完全确定如何使用 .get() 函数进行搜索。

这是我的查询 Seller.get({ "PK": "imin@cats.com", "SK" : "MY" }),这显然不是我想要的。

我知道我也许可以像下面这样使用过滤器,但我在很多地方读到不推荐使用过滤器 (?)

var filter = new dynamoose.Condition().where("PK").eq(email).filter("SK").beginsWith("MY_");
var premiseProfile = await Seller.query(filter).exec()

以下是我的卖家的架构 table

const schema = new dynamoose.Schema({
    PK: {
        type: String,   
        hashKey: true,
    },
    SK: {
        type: String,   
        rangeKey: true,
    },
    "firstName": String,
    "lastName": String,
    "gender": {
        "type": Number,
        "default": 0
    },
}, {
    "saveUnknown": true,
    "timestamps": true
});

进行 Model.get 调用时,您必须传入整个密钥。您不能传入以开头的键。这是因为 Model.get 只会 return 1 个项目,而查询表明您可以在那里有多个项目。

很难准确回答您的问题,因为您没有 post 您的架构。但看起来在这种情况下执行 query 并不坏,因为您查询的是数据而不是过滤数据。


根据评论获得更多信息。

我意识到 condition.filter documentation 并没有像它应该的那样真正涵盖这一点。基本上取决于您的模式,它将确定最佳索引,并以它知道的最佳方式对其进行优化。

例如,如果您有以下代码:

const dynamoose = require("dynamoose");

(async () => {
    dynamoose.model.defaults.set({
        "create": false,
        "waitForActive": false
    });

    const schema = new dynamoose.Schema({
        "PK": {
            "type": String,
            "hashKey": true
        },
        "SK": {
            "type": String,
            "rangeKey": true
        }
    });

    const Model = dynamoose.model("User", schema);

    dynamoose.logger.providers.add(console);

    const filter = new dynamoose.Condition().where("PK").eq("test@test.com").filter("SK").beginsWith("MY_");
    const premiseProfile = await Model.query(filter).exec()
})();

它将产生以下输出:

aws:dynamodb:query:request - {
    "ExpressionAttributeNames": {
        "#qha": "PK",
        "#qra": "SK"
    },
    "ExpressionAttributeValues": {
        ":qhv": {
            "S": "test@test.com"
        },
        ":qrv": {
            "S": "MY_"
        }
    },
    "TableName": "User",
    "KeyConditionExpression": "#qha = :qhv AND begins_with (#qra, :qrv)"
}

如您所见,它使用 KeyConditionExpression 而不是 FilterExpression

所以你没有过滤。如果它对您更有意义,您可以使用 condition.wherecondition.attribute.

需要注意的是,在某些情况下它会使用 FilterExpression。但它会首先查看您的架构并尝试查看它是否可以使用 KeyConditionExpression,如果可以,它将使用那个,否则它将使用 FilterExpression.