【问题标题】:Using IN operator in FilterExpression on numeric array在数值数组的 FilterExpression 中使用 IN 运算符
【发布时间】:2021-09-03 04:49:35
【问题描述】:

我正在尝试使 AWS Lambda 与 DynamoDB 表交互,但我似乎无法正确生成 scan() 查询:
在我的场景中,我们有两张桌子,一张包含老师,一张包含他们的讲座。每位老师都有 1 个以上的科目要教,每节课都涉及该老师的一个科目。
我想从lectures 表中获取特定教师的每堂课(给定其标识符)。
到目前为止,我已经尝试过:

exports.handler = async(event, context, callback) => {
   
    var courses_ids = "";
    event.courses.forEach(function (course) {
       courses_ids+=''+course.id+ ', ';
    });
    courses_ids = courses_ids.substring(0, courses_ids.length -2);
    console.log("Courses IDs: " + courses_ids); // -> 1, 2, 3
  
    await retrieveLecturesOfTeacher(courses_ids).then(data => {
       console.log("Resulting data: "+JSON.stringify(data.Item))
       // TODO
    });
};

function retrieveLecturesOfTeacher(courses_ids) {
    var filter_expression = 'course_id IN ( '+courses_ids+' ) ';
    console.log("Filter Expression: "+filter_expression);
    const params = {
        TableName: 'lectures',
        FilterExpression: 'course_id IN ( :courses_ids )' ,
        ExpressionAttributeValues: {
            ':courses_ids' : courses_ids
        }
    }
    console.log("Params: "+JSON.stringify(params))
    return ddb.scan(params).promise();
}

但是没有找到课程 1,2 和 3 的讲座(尽管它们存在于数据库中)。

Function Logs:
   INFO    Params: {"TableName":"lezioni","FilterExpression":"id_corso IN ( :courses_ids )","ExpressionAttributeValues":{":courses_ids":"undefined, undefined"}} 
   INFO    Resulting data: null

但是如下替换参数可以解决问题:

const params = {
    TableName: 'lectures',
    FilterExpression: 'course_id IN ( :course_1, :course_2, :course_3) ',
    ExpressionAttributeValues: {
        ':course_1' : 1,
        ':course_2' : 2,
        ':course_3' : 3
    }
}

我已经检查了thisthis 问题,但我的问题似乎与数据类型有关,因为演讲表中的course_id 是一个数字,而我的courses_ids 变量是一个字符串。有没有解决方案(同时考虑到老师可以有任意数量的考试)?

【问题讨论】:

  • 你说没有找到讲座,但是扫描返回了什么?您能打印出params 哈希值,以便我们查看要扫描的内容吗?
  • @SethGeoghegan 我添加了函数输入和输出,但是我找到了解决方案,所以我将在今天晚些时候发布答案
  • 太棒了!很高兴您找到了解决方案。

标签: javascript node.js amazon-web-services aws-lambda amazon-dynamodb


【解决方案1】:

从问题中可以看出,主要问题似乎是类型差异,特别是如下更改测试会导致失败(因为它会产生Resulting data: undefined):

const params = {
    TableName: 'lezioni',
    FilterExpression: 'id_corso IN ( :course_1, :course_2, :course_3) ',
    ExpressionAttributeValues: {
        ':course_1' : "1",
        ':course_2' : "2",
        ':course_3' : "3"
    }
}

因此,由于无法生成正确检索讲座的字符串,因此我必须找到一个工作区来保留数据类型:特别是动态创建FilterExpression 字符串和ExpressionAttributeValues 映射。我特此报告更正后的代码。

exports.handler = async(event, context, callback) => {
    
    var lectures_map = {};
    var i = 0;
    var query_string = "";
    
    event.corsi.forEach(function (course) {
       lectures_map[":value_"+i] = course.course_id;
       query_string += ":value_"+i+", ";
       i+=1;
    });
    
    query_string = query_string.substring(0, query_string.length -2);
  
    await retrieveLecturesOfTeacher(query_string, lectures_map).then(data => {
        event.lectures = data;
        callback(null, event);
    });
};

function retrieveLecturesOfTeacher(query_string, attribute_values) {
    var filterExpression = 'course_id IN ( '+query_string+' ) '
    const params = {
        TableName: 'lectures',
        FilterExpression: filterExpression,
        ExpressionAttributeValues: attribute_values
    }
    console.log("Params: "+JSON.stringify(params))
    return ddb.scan(params).promise();
}

这里是scan参数

Function Logs:
    INFO    Params: {"TableName":"lezioni","FilterExpression":"id_corso IN ( :value_0, :value_1 ) ","ExpressionAttributeValues":{":value_0":1,":value_1":2}}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    • 1970-01-01
    相关资源
    最近更新 更多