Search code examples
javascriptsqlnode.jspostgresqlpg

Interpolating an array into a Javascript Postgres query


So I'm working in Node.js and using the 'pg' npm module. I'm trying to check to see if the contents of an array are contained within an array that's stored in a Postgres table (the order doesn't matter to me--it should return true if there is a 1:1 element ration between arrays).

The Postgres query looks like this:

let getComFromMembers = `SELECT * FROM ComTable WHERE (members @> ($1) AND members <@ ($1))`

In my javascript, I'm calling it like this:

let results = await client.query(getComFromMembers, [numberMembers]);

numberMembers is an array that was originally pulled from Postgres, and then mapped to a number array:

let postgresArray = []
// query tables and populate postgresArray with .push()
let numberArray = postgresArray.map(Number)

For some reason, I'm not getting anything back from 'results'. As an example, in the case where numberArray would be an array with elements 1, 2, and 3, look below.

To get it to work I need to query directly into my database:

SELECT * FROM ComTable WHERE (members @> '{1,2,3}' AND members <@ '{1,2,3}')

Solution

  • I believe you need to execute the query like so:

    let getComFromMembers = `SELECT * FROM ComTable WHERE members @> $1 AND members <@ $1`;
    let numberMembers = [101, 212, 333];
    let results = await client.query(getComFromMembers, ["{" + numberMembers.join(",") + "}"]);
    

    But the proper solution would be to "generate" and execute the query as follows:

    let numberMembers = [101, 212, 333];
    
    let placeHolder = numberMembers.map((_, i) => `$${i+1}`).join(", ");
    // the result would be "$1, $2, $3"
    
    let getComFromMembers = `SELECT * FROM ComTable WHERE members @> ARRAY[${placeHolder}]::integer[] AND members <@ ARRAY[${placeHolder}]::integer[]`;
    // the result would be "SELECT * FROM ComTable WHERE members @> ARRAY[$1, $2, $3]::integer[] AND members <@ ARRAY[$1, $2, $3]::integer[]"
    getComFromMembers;
    
    let results = await client.query(getComFromMembers, numberMembers);