How to get all revisions document with single request in couchdb? - node.js

I use nano.js as couchdb driver in my express app. i managed to get document revision's id with command like this
db.get(id, { revs_info: true }, function(err, inventory){
res.send(inventory);
})
which returns the latest revisions with _revs_info in it. Unfortunately _rev_info only includes revision number and availability status.
{ _id: 'doc',
_rev: '3-825cb35de44c433bfb2df415563a19de',
_revs_info:
[ { rev: '3-825cb35de44c433bfb2df415563a19de',
status: 'available' },
{ rev: '2-7051cbe5c8faecd085a3fa619e6e6337',
status: 'available' },
{ rev: '1-967a00dff5e02add41819138abb3284d',
status: 'available' } ]
}
so how to get all revision's document with single request in couchdb ?

Related

How to return field based on other fields with mongoose

I have mongoose schema that looks something like this:
{
_id: someId,
name: 'mike',
keys: {
apiKey: 'fsddsfdsfdsffds',
secretKey: 'sddfsfdsfdsfdsds'
}
}
I don't want to send back to the front the keys of course, but I want some indication, like:
{
_id: someId,
name: 'mike',
hasKeys: true
}
There is built in way to create 'field' on the way based on other fields, or do I need every time fetch the whole document, check if keys is not empty and set object property based on that?
For Mongo version 4.2+ What you're looking for is called pipelined updates, it let's you use a (restricted) aggregate pipeline as your update allowing the usage of existing field values.
Here is a toy example with your data:
db.collection.updateOne(
{ _id: someId },
[
{
"$set": {
"hasKeys": {
$cond: [
{
$ifNull: [
"$keys",
false
]
},
true,
false
]
}
}
},
])
Mongo Playground
For older Mongo versions you have to do it in code.
If you don't want to update the actual document but just populate this field when you fetch it you can use the same aggregation to fetch the document
you can use $project in mongoose aggregation like this.
$project: { hasKeys: { $cond: [{ $eq: ['$keys', null] }, false, true]}}

Need to update the elastic search doc without id field with nodejs client

I have docs in elastic search having no id field in them, I have some other field _id as a unique identifier.
I want to update the doc by _id field via nodejs client, but it is throwing an error Missing required parameter: id
One solution can be, to reindex the whole doc.
Any other suggestions are welcome
I am using following query
await esClient.updateByQuery({
index: 'storyv2',
refresh: true,
body: {
script: {
lang: 'painless',
source: 'ctx._source.like = 100',
},
query: {
match: {
_id: storyId,
},
},
},
});
Elastic version: 2.2
Elastic nodejs client version: 7.10.0
You can also update your documents by query:
POST your-index/_update_by_query
{
"script": {
"source": " ...do something to your document... ",
"lang": "painless"
},
"query": {
"term": {
"unique-id-field": "the-doc-id-to-update"
}
}
}
UPDATE:
await esClient.updateByQuery({
index: 'storyv2',
type: '_doc', <--- add this
refresh: true,
body: {
script: {
lang: 'painless',
source: 'ctx._source.like = 100',
},
query: {
match: {
_id: storyId,
},
},
},
});

Mongoose aggregate, Match, Count, Group

I am trying to send a list of total paid and unpaid client with count along with data from my node API.
In mongoose method, I am stuck at thinking how to go further.
can anyone suggest the best way to achieve this?
router.get("/", ensureAuthenticated, (req, res) => {
Loan.aggregate([
{
$match: {
ePaidunpaid: "Unpaid"
}
}
]).then(function(data) {
console.log(data);
res.render("dashboard", { admin: req.user.eUserType, user: req.user,data:data });
});
});
Loan Model:
const Loan = new Schema({
sName: { type: String },
sPurpose: [String],
sBankName: String,
sBranchName: [String],
nTotalFees: { type: Number },
ePaidunpaid: { type: String ,default:'Unpaid'},
sCashOrCheque: { type: String },
});
Outcome:
Details of a user with a count of paid and unpaid clients
[
Paid:{
// Paid users
},
Unpaid:{
// Unpaid Users
},
]
Well in that case, try this -
Loan.aggregate([
{
$group: {
_id: "$ePaidunpaid",
data: { $push: "$$ROOT" },
count: { $sum: 1 }
}
}
]);
Output would be something like this -
{
"_id": "Paid",
"data": [
// All the documents having ePaidunpaid = Paid
{ _id: "asdasd123 1eqdsada", sName: "Some name", // Rest of the fields },
{ _id: "asdasd123 1eqdsada", sName: "Some name", // Rest of the fields }
],
count: 2
},
{
"_id": "Unpaid",
"data": [
// All the documents of having ePaidunpaid = Unpaid
{ _id: "asdasd123 1eqdsada", sName: "Some name", // Rest of the fields },
{ _id: "asdasd123 1eqdsada", sName: "Some name", // Rest of the fields }
],
count: 2
},
Explanation
First stage of the pipeline $group groups all the documents according to ePaidunpaidfield which only have two values Paid or Unpaid thus rendering only two documents respectively.
Next step is to accumulate original data (documents) being grouped together. This is achieved using $push accumulator on data field, pushing $$ROOT which effectively references the document currently being processed by pipeline stage.
Since you needed count of all paid and unpaid users hence a $sum accumulator to count all the items in each group.

Elasticsearch _bulk update issue giving VersionConflictEngineException message

I am using elasticsearch in one of my project. I am facing an issue while updating a record. The error message that I am getting is:-
{ _index: 'makes',
_type: 'make',
_id: '55b8cdbae36236490d00002a',
status: 409,
error: 'VersionConflictEngineException[[makes][0] [make][55b8cdbae36236490d00002a]: version conflict, current [168], provided [167]]' }
Using ES bulk api. My application is in node.js.
Let me share my code too:-
var conditions = [];
conditions.push({
update: {
_index: config.elasticSearch.index,
_type: config.elasticSearch.type,
_id: id
}
});
conditions.push({
doc: {
published: true
}
});
client.bulk({
body: conditions
}, function(err, resp) {
console.log(resp);
console.log(resp.items[0].update);
return res.send({success: true, message: "Shows updated successful"})
});
The below is the value of conditions array:
[ { update:
{ _index: 'makes',
_type: 'make',
_id: '55b8cdbae36236490d00002a' } },
{ doc: { published: true } } ]
When you start querying a record, its response with the record including the version of that record. When you want to update it, but before it, it has been updated by another, the record in the database has a higher version than what the client thinks.
This may happen because some operation are still in queue, so you get the unprocessed record (hence lower version). When this happens, try https://www.elastic.co/guide/en/elasticsearch/reference/1.6/indices-refresh.html:
curl -XPOST 'http://localhost:9200/{your_index}/_refresh'
Then call your method again

mongodb select either both documents or none

I am in situation where I have to update either two documents or none of them, how is it possible to implement such behavior with mongo?
// nodejs mongodb driver
Bus.update({
"_id": { $in: [ObjectId("abc"), ObjectId("def")] },
"seats": { $gt: 0 }
}, {
$inc: { "seats": -1 }
}, { multi: true }, function(error, update) {
assert(update.result.nModified === 2)
})
The problem with code above it will update even if only one bus matched. In my case I try to book ticket for bus in both directions and should fail if at least one of them already fully booked.
Thank you

Resources