Open LucasBadico opened 6 years ago
If you have a class defined as:
@table(config.DDB_TABLE)
class MyRecord {
@hashKey()
email?: string;
@attribute()
passwordHash?: string;
@attribute()
passwordSalt?: string;
@attribute()
verified?: boolean;
@attribute()
verifyToken?: string;
}
Then you could execute the update as:
const aRecord = Object.assign(new MyRecord(), {
email,
passwordHash: password,
passwordSalt: salt,
verified: false,
verifyToken: token,
});
mapper.put(aRecord, {
condition: new FunctionExpression('attribute_not_exists', new AttributePath('email')
}).then( /* result handler */ );
Can I put this on the readme of expressions?
Hey guys. testing this here is not working, still add a new item with the same email.
@jeskew a funny thing... look at this...
This is my test. It is not working as expected...
import {
FunctionExpression,
AttributePath,
} from '@aws/dynamodb-expressions'
import { User, connection, Repository } from '../src/domain-user'
const user = new User({
accountId: '2e2b043f-47e2-40d8-878d-829bc06af003',
// username: 'customer-123',
createdAt: (new Date()).toString()
})
console.log(new FunctionExpression('attribute_not_exists', new AttributePath('accountId')))
connection.mapper.put(user, {
condition: new FunctionExpression('attribute_not_exists', new AttributePath('accountId'))
}).then(console.log).catch(console.error)
{ ConditionalCheckFailedException: The conditional request failed
at Request.extractError (/developer/project/node_modules/aws-sdk/lib/protocol/json.js:48:27)
at Request.callListeners (/developer/project/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/developer/project/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/developer/project/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/developer/project/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/developer/project/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /developer/project/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/developer/project/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/developer/project/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/developer/project/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
message: 'The conditional request failed',
code: 'ConditionalCheckFailedException',
time: 2018-08-18T01:48:50.981Z,
requestId: 'GBLH99R2PTHE65M97OF7LI48URVV4KQNSO5AEMVJF66Q9ASUAAJG',
statusCode: 400,
retryable: false,
retryDelay: 26.5584118220047 }
it is aways throwing this error. And is writing a new item every time.
Still struggling... but now I think that is more straight foword aswer. I have this filter operation:
export function getByCpf({ cpf, merchantId}) {
return new Promise((resolve, reject) => this.client.query({
TableName: tableName,
KeyConditionExpression: "merchantId = :id",
FilterExpression: 'documents[0].documentNumber = :cpf',
ExpressionAttributeValues: {
":cpf" : {
S: cpf,
},
":id": {
S: merchantId,
}
}
}, (err, {Items}) => {
if (err) {
return reject(err)
}
return resolve(Items)
})
)
}
How use the filter on the data mapper?
await mapper.get(myClass, {filter: ???})
I have been playing with these library for a while, this is my proposed function using datamapper. I don't know whether documents[0].documentNumber
will fail the function or not, as I never encounter such key before.
import { equals } from '@aws/dynamodb-expressions';
export async function getByCpf({ cpf, merchantId }) {
const keyCondition = {
merchantId: merchantId,
}
const predicate = equals(cpf);
const filterCondition = {
...predicate,
subject: 'documents[0].documentNumber'
}
const queryOptions = {
filter: filterCondition
}
const iterator = mapper.query(myClass, keyCondition, queryOptions);
let result = [];
for await (const record of iterator) {
result.push(record);
}
return result;
}
queryOptions
will be translated as follows :
queryOptions = {
filter:
{
type: 'Equals',
object: cpf,
subject: 'documents[0].documentNumber'
}
}
You can find full documentation about other expression here https://awslabs.github.io/dynamodb-data-mapper-js/packages/dynamodb-expressions/
Nice! Thanks @puzzloholic I will implement
How would you use the FunctionExpression with the 'size'-Function? The following is not working unfortunately. https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions
new FunctionExpression('size', new AttributePath('aAttributeWithStringSetAsType'), '> 0')
I really have been strugly to undestand how to use it. For example, I need to make my dynamodb just make a update(acting as a create) if there is no
username
. I know that to doing that I have to do this:How I make this a operation with the
mapper
andexpressions
lib?