How to remove last element in set in dynamo? - node.js

I have created a set using dynamoDB document client . I am able to remove items in this set however when i remove to the last element in the set nothing returns until i make a new post. Then all the other data is displayed.
const params = {
TableName: 'beta-user-' + process.env.NODE_ENV,
Key: {
username: request.username
},
UpdateExpression: "DELETE #features :feature",
ExpressionAttributeNames: { "#features" : "features" },
ExpressionAttributeValues: { ":feature": dynamodb.createSet([request.feature]) },
ReturnValues: "NONE"
};
and im calling it like
const dynamoPromise = dynamodb.update(params).promise();
return await dynamoPromise.then(result => { // stuff })
The UpdateExpression i do not think is wrong
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.DELETE
I belive the problem is with ExpressionAttributeValues if i remove
dynamodb.createSet I get many validation errors.
When i make a get request to app i get
{
"message": [
{
"username": "x",
"feature": [
"blah",
"test"
]
},
{
"username": "z",
"feature": [
"blah"
]
},
}
I make a delete request and remove the feature test from username x. This works and returns the same response minus the test feature. I make another delete request to remove blah. Blah is removed however when I make a get request I recieve:
{
"message": {}
}
The other data is returned when i make a new post to that specific user.
EDIT:
I think the issue might be due to dynamo not liking an empty set

The issue was with my return statement in my get request. I assumed that once features were deleted the record would be deleted. I was trying to return features on an object that had no features, therefore, it was erroring out and not returning anything.

Related

(NodeJS) WordPress API, updating Events Calendar event (tribe event) removes featured image from post

I'm using the Wordpress API to update tribe events. The updates are successfully sent (and the change is made) but as a side-effect, any time I do it, the featured image is removed from the post...
wpapi package setup:
Because The Events Calendar has it's own routes that aren't built-in by default in the wpapi package, I use the wp.registerRoute function to set that up. I don't think there's a problem with the way I set that up because otherwise it works.
var WPAPI = require( 'wpapi' );
var wp = new WPAPI({
endpoint: 'https://www.example.com/wp-json',
username: 'username',
password: 'mypassword'
});
wp.tribeevent = wp.registerRoute('tribe/events/v1', '/events/(?P<id>)');
example update:
function showEvent (post_id) {
let data = { "hide_from_listings" : false }
wp.tribeevent().id(post_id).update(data)
}
Haven't been able to find anyone with this issue online, so I'm posting here after exhausting myself trying to get it to work without removing the image... Am I doing this wrong? Is this just a bug? Any suggested workarounds?
I've also tried adding the existing image info into the update data sent, but I get this response when doing so:
{
"error": {
"code": "rest_invalid_param",
"message": "Invalid parameter(s): image",
"data": {
"status": 400,
"params": {
"image": "Invalid parameter."
},
"details": []
}
}
}
Otherwise, when making an update such as { "hide_from_listings" : false }, when the json response comes back, the value of the image key just comes back as false: { "image" : false }
Would greatly appreciate any kind of input on this issue...

Problems with "updateMany" and "$pull" on array properties

I have the following object in my mongodb:
{
"item": {
"id": "/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8=",
"status": {
"likes": [
"HU0HKFoL2YQuQ2WrYhj0rYoFbRkwJ0EJEf4ML7vAp2Q="
]
}
}
}
Now I want to update my collection, and pull the value "/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8=" from all documents in the collection who have this value in their item.status.liles array.
When I use the tool Robo 3T, I can put into the command line:
db.getCollection('mycollection').update({"item.status.likes": "/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8=" }, { "$pull":{"item.status.likes": "/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8="}})
And it says Updated 0 record(s) in 2ms when I execute the command (which is correct, since there is no document matching).
Now when I do the same in Node.JS code, like this:
let filter = {item.status.likes: '/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8='};
let obj = {"$pull":{"item.status.likes":"/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8="}}
collection.updateMany(filter, obj, { upsert: true }, (err, info) => {...});
I get MongoError: Cannot apply $pull to a non-array value instead.
If I change it to:
collection.updateMany({}, obj, { upsert: true }, (err, info) => {...});
I get no error. This leads me to believe that there is a difference between "no filter" and "empty result set", and $pull does not work on the latter.
Why is this? I also tried with different "$pull"-syntax (e.g. {"item":{"status":{"likes"... vs item.status.likes) but this didnt change anything.
The error happens when there is no single document matching the filter because of upsert: true.
It tells mongo to insert a new document with fields from the filter, which makes following document:
{
"item": {
"status": {
"likes": "/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8="
}
}
}
Then it tries to apply the update to this document calling $pull on the string which results with the error.
The Robo3T version works because the update is upsert: false by default.

Removing attribute from map in dynamodb

I have the following dynamodb table and want to remove "oldInfo" from the attribute "accounts" using update_expression = f"REMOVE accounts.oldInfo" however that does not work. Does anyone have any ideas or suggestions for this? Note that the "accounts" attribute is a map and so is "oldInfo".
{
"accounts": {
"oldInfo": {
"oldStuff": []
}
"otherInfo": {
"otherStuff": []
}
}
}
This is the code that I am using to remove "oldInfo"
self.clean_up_dynamo_db.updateitem(table_name=self.table_name,
key={
"partitionKey": item["partitionKey"],
"sortKey": item["sortKey"]
},
update_expression=f"REMOVE {self.attribute}")
I didn't find a clear example in the DDB docs, so I replicated your situation in my AWS account.
I created a map attribute named accounts and gave it keys of oldInfo and otherInfo. I executed the following operation, which removed accounts.oldInfo as expected.
const params = {
TableName: "YOUR_TABLE_NAME",
Key: {
PK: "PARTITION_KEY",
SK: "SORT_KEY"
},
UpdateExpression: "REMOVE accounts.otherInfo"
}
await ddbClient.updateItem(params);
Although this snippet is in JavaScript, it confirms that you are going about the operation correctly according to the DDB API.
Perhaps there is something else going on in your code that is preventing the operation from succeeding? Are you certain the variables you are sending update_item are as you expect them?

How to resolve Trying to create too many scroll contexts. Must be less than or equal to: [500]?

I'm trying to query from Elastic DB. So for 90000 Records I need to hit elastic DB for two different occasions.My query is as follows.
var queryobj = {
"query": {
"bool": {
"must": [
{
"match": {
"mobile": value
}
}
],
}
}
};
var { _scroll_id, hits, took } = await elasticClient.search({
index: 'mobiledata',
type: '_doc',
scroll: '20m',
filterPath: '_scroll_id,hits.hits._source,took',
size: 10000,
body: queryobj
});
if (hits) {
console.log("hits ", hits);
return hits.hits;
}
return hits;
While trying to exectue this, I'm getting error like :
{ Error: [exception] Trying to create too many scroll contexts. Must be less than or equal to:
[500]. This limit can be set by changing the [search.max_open_scroll_context] setting.
status: 500,
displayName: 'InternalServerError',
message: '[exception] Trying to create too many scroll contexts. Must be less than or equal to:
[500]. This limit can be set by changing the [search.max_open_scroll_context] setting.',
Can anybody help me how to fix this error?
await elasticClient.clearScroll({scroll_id: _scroll_id});
Whenever you want to close the scroll api and open another scroll api, please run the above code.
It works fine for me.

Mongoose FindOneandUpdate - Only update Specific fields leave others alone

Maybe I'm not wording this properly but hopefully I can find some help with this. I've been playing around with mongoose schema's and boy its doing my head in with this issue..
I want to update a document on a collection under a specific ID, I've got all that working however. I'm running into an issue where since I never supplied values for others I dont want updated it makes them either all Null or deletes them if omitUndefined is turned on.
router.put('/api/playerinfo/:player_steamID/main_server', passport.authenticate('basic', {session: false}),
function(req, res){
const params = {
main_server: {
game_stats:{
kills: req.body.main_server.game_stats.kills,
deaths: req.body.main_server.game_stats.deaths,
}
}
};
PlayerInfo.findOneAndUpdate({player_steamID: req.body.player_steamID }, {$set: params}, { upsert: true, new: true }).then(playerinfo =>{
res.json(playerinfo)
});
});
For example:
Current Stored information
{
"name": "Jimbo",
"steamID": "123456",
"main_server": {
"game_stats": {
"kills": 3,
"deaths":0
}
}
}
Then if we used the above code to modify the fields.. But we did not supply a death value for that field, it would null out the bottom or remove it entirely if omit is true.
Sending postman update with the following:
{
"name": "Jimbo",
"steamID": "123456",
"main_server": {
"game_stats": {
"kills": 34
}
}
}
Updated Information
{
"name": "Jimbo",
"steamID": "123456",
"main_server": {
"game_stats": {
"kills": 34,
"deaths": null
}
}
}
What I would like to know is the best way to modify multiple fields without it "changing" the last value. if a field is missing. Is that possible?
IE: If i only supply kills value and leave json update for deaths blank it would retain the old value from deaths.
Thanks.
-- Fixed.
created a object inside $set then to update old values without replacing you need to wrap them in quotes. 'main_server.game_stats.kills' : req.body.....kills etc.
Use $set to update only certain fields.
PlayerInfo.findOneAndUpdate({steamID: req.body.steamID },{ $set: {'yourcoll.$.someField': 'Value'} }, { upsert: true, new: true }).then(playerinfo =>{
res.json(playerinfo)
});
Documentation:
https://docs.mongodb.com/manual/reference/operator/update/set/
Fixed. created a object inside $set then to update old values without replacing you need to wrap them in quotes. 'main_server.game_stats.kills' : req.body.....kills etc.
I also did a for loop in the object and assigned props to handle multiple values or single if passed through from json.
You can try just put part of model, which contains specific field for update
_userModelRepository.updateUser( { email: req.user.email }, { specificField: specificValue});
Here's schema implementation
updateUser = function(query, params){
return _userModelRepository.findOneAndUpdate(query, params, function(err, result) {
if (err) {
throw err;
}
});
}
What I did was
retrieve the original value in hidden input field using Ejs something like:
<input type="hidden" name="nameOf_thefield" value="<%= variable %>" />
Pass the value req.body.nameOf_thefield to the variable which you wish not to change

Resources