node-elastic full document update - node.js

In my nodejs elastic writer I want to replace one document with another.
Currently, I run-
var data = { doc: doc, "doc_as_upsert": true };
var metadata =
{ update: { _id: idToUpdate, _index:indexName,_type: INDEX_TYPE_PREFIX } };
body.push(metadata);
body.push(payment);
}
elasticsearchClient.bulk({
body: body,
}, function (err, resp) {
But in case the document in elastic contained field X and the updated document didn't, field X stays in elastic- I want it to be removed.
According to
https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html
using "doc:" is for partial update, so what's the alternative for full update?

Don't use the update api, use the index api instead.

Related

Update element of any particular index in an array in MongoDb using mongoose in Node.js

Hi I tried to update the element at a particular index in an array but I'm not able to update it. It is updating the entire array. Not able to figure out how to update any particular index. Also tried
{$set:{"Data.1:req.body}}
this is updating at 1st index but I don't want to hardcode the index value. It should take from frontend. Let say I have a schema in which I have Data who's type is array and default value is as shown below or anything in the same format.
Data: {
type: Array,
Default: ["0","1","0"]
}
Whenever I'll create a user then Data field will contain these default values, But now I want to update the value at any index (coming from frontend) of Data array of any user created.
I tried findByIdAndUpdate method but I don't know what to pass in set property. If I'm passing this {$set: req.body} and In postman I'm giving any value of Data then obviously it is updating Data array but I want to update value at any index which I'm passing from frontend, let say the index I'm passing is 2 then it should update the value of array at index 2, similarly I can pass any index from frontend how should I do that. What changes I have to make in {$set : } Thanks in advance.
Waiting for any help or suggestions. Thanks
It appears that you can solve this in backend logic if you are passing the index from the frontend.
You can dynamically specify the index, based on the input from the frontend, before you send a query.
const updateUserData = async (req, res) => {
const { index, user_id, new_value } = req.body;
try {
const update = {};
update[`Data.${index}`] = new_value;
const data = await Users.updateOne(
{ _id: user_id },
{ $set: update }
);
return res.status(200).json({ success: true });
} catch (error) {
return res.status(500).json({ success: false });
}
};

I want to insert documents using upsert in mongoose

I am fetching data from an external api and I want to insert multiple records if they are not already there . I am creating an array of objects like this :
data=[
{
match_id: 212167781,
player1Id: 129753806,
player2Id: 129753811,
player1Details: '5f070c8f79f62c00042b0cd8',
player2Details: '5f3267fe6a0f891b3604b999'
},
{
match_id: 212167782,
player1Id: 129753799,
player2Id: null,
player1Details: '5f070ade79f62c00042b0cd6'
}
]
Now for instance if the second record is not already present then I want it to be inserted and I have tried upsert but nothing happens . Please help .
You should be able to do this using a simple loop and Model.findOneAndUpdate in combination with the upsert option:
async function upsertMany(data) {
for(const entry of data) {
await YourModel.findOneAndUpdate(entry, entry, { upsert: true });
}
}
// call this with your data-array
await upsertMany(data);

Mongoose get updated document after instance.update()

I am executing a mongoose Model.findById() function in order to return a single instance by utilizing an express route.
Model.findById(modelid)
.then(instance => {
if(instance.isOwnedBy(user)) {
return instance.update({$push: {days: req.params.dayid}}, {new: true})
.then(foo => res.send(foo))
} else {
res.status(401).send("Unauthorized")
}
})
the above code returns an object containing the opTime, electionId...etc instead of returning the newly updated document instance. How am I able return the newly updated document after the instance.update() method?
If instance.isOwnedBy(user) and _id: modelid can be merged into one mongo query, it's better to use findOneAndUpdate() but in that way, if it doesn't find any document match, you can not know which part of the query causes the not found.
And because I don't know much about your models, conditions, I can not answer how to do it with findOneAndUpdate() but there is another way that modify the document and call save() method.
Example base on your code:
Model.findById(modelid)
.then(instance => {
if(instance && instance.isOwnedBy(user)) {
if(instance.days) instance.days.push(req.params.dayid);
else instance.days = [req.params.dayid];
instance.save().then(function(instance){
res.send(instance);
})
} else {
res.status(401).send("Unauthorized")
}
})
Note: You should check if the instance exist or not before modify it.

What is the best way to get the latest record belonging to a partition key using the azure-storage node library?

Can someone recommend the best solution for getting the latest record belonging to a partition key when using the azure-storage library in Node? Since there is no .orderBy() option... what is the best approach?
In C# I would probably do something like:
var latestRecord = results.OrderByDescending(r => r.Timestamp).FirstOrDefault();
What would the equivalent be when using this node library for Table Storage?
We need to implement custom compare function to sort the results.
tableService.queryEntities(tableName, query, null, function(error, result, response) {
if (!error) {
var latestRecord = result.entries.sort((a,b)=>{
return new Date(b.Timestamp._) - new Date(a.Timestamp._);
})[0])
}});
Results are decorated with Edm type, so we need b.Timestamp._.
Timestamp: { '$': 'Edm.DateTime', _: 2018-10-26T07:32:58.490Z }
If this format is somehow unpleasant, we can get entities without metadata from response. Need to set payloadFormat.
tableService.queryEntities(tableName, query, null, {payloadFormat:azure.TableUtilities.PayloadFormat.NO_METADATA},function(error, result, response) {
if (!error) {
var latestRecord = response.body.value.sort((a,b)=>{
return new Date(b.Timestamp) - new Date(a.Timestamp);
})[0]
}});

Loopback Find then update attribute or delete by id

Been trying to find samples usage for some of the static methods for a persistedModel in Loopback.
https://apidocs.strongloop.com/loopback/#persistedmodel-prototype-updateattribute
it just says:
persistedModel.updateAttributes(data, callback)
But how you I choose the which record I want to update? this is not working for me.
var order = Order.setId('whateverrecordId');
order.updateAttributes({name:'new name'},callback)
Loving loopback.. but their doc, sucks.. :(
You can use those on event listener like AfterSave
example:
Model.observe('after save', function(ctx, next) {
ctx.instance.updateAttribute(fieldname:'new value');
next();
});
1- What you did was right but i do not advise this method it's used for instance methods and generally to update fields like date for all the collection that you have so you don't need an id for it.
But you can try to make an array containing data to update containing also the ids and then make a comparison to fill in data for the ids that you have. (in #dosomething)
order.find().then(function(orders) {
orders.forEach(function(element) {
order.setId(element.id);
#DoSomething
order.updateAttribute({new: data}, function(err, instance) {
console.log(instance);
})
});
})
2- You can use updateAll to update one or many attribute.
PersistedModel.updateAll([where], data, callback)
var Updates = [{id : 1, name: name1}, ...]
Updates.forEach(function(element) {
order.updateAll({id : element.id}, {name :element.name}, function(err, count) {
if (err) {
console.error(err);
}
console.log(count); // number of data updated
})
})

Resources