在数字数组的 FilterExpression 中使用 IN 运算符

Using IN operator in FilterExpression on numeric array

我正在尝试使 AWS Lambda 与 DynamoDB 交互 table 但我似乎无法正确生成 scan() 查询:
在我的场景中,我们有 2 个 table,一个包含教师,一个包含他们的讲座。每个老师有 1+ 个科目要教,每节课都参考老师的一个科目。
我想从 lectures table 中获取特定老师的每节课(给定其标识符)。
到目前为止我试过这个:

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
    }
}

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

从问题中可以看出,主要问题似乎是类型差异,特别是如下更改测试将导致失败(因为它将产生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}}