var query = mycouchbase.view('doc', 'myview');
query.query({
limit: 1
}, function(err, results) {
for (i in results) console.log(results[i]);
});
in couchbase admin console what I saw is
but in javascript console
console - { id: '1NR10', key: '1NR10', value: null }
value always is null
your comment welcome
I think by default "IncludeDocs" is false, so you will need to explicitly set IncludeDocs: true (please check exacte syntax in the documentation)
Related
I’m having trouble with upsert with meteor.js. I could update questions finely with the below codes but I won’t be able to insert new data.
file in client side
const onSave = () =>{
// there is more codes but omitted
questions.forEach(question => {
Meteor.call('modifyQuestion', question);
})
}
file in server side (collection file)
modifyQuestion(question) {
check(question, Object);
const questionId = Measures.findOne({questionId: question._id});
Measures.upsert(
{_id: questionId._id},
{
$set: {
title: question.text,
},
},
);
},
Got error saying…
Exception while simulating the effect of invoking 'modifyQuestion' TypeError: Cannot read properties of undefined (reading '_id')
I thought when {_id: questionId._id} got undefined, that’s the time upsert understand that there is no matching data found and insert one as new data into the database.
Is this wrong?
I switched $set to $setOnInsert, but still didn't work...
ADDED
Now I don't see any error but i couldn't insert new data. I could update data tho.
modifyQuestion(question) {
check(question, Object);
Measures.upsert(
{questionId: question._id}, // changed
{
$set: {
title: question.text,
},
$setOnInsert: {type: 'multipleChoice'}
},
);
},
Also removed const questionId = Measures..... part
You still need to set the questionId on insert:
modifyQuestion(question) {
check(question, Object);
Measures.upsert(
{ questionId: question._id },
{
$set: {
title: question.text,
},
$setOnInsert: {
questionId: question._id
type: 'multipleChoice'
}
},
);
},
Otherwise there will never be a doc that contains the questionId.
Note: Another helpful tool would be Collection2 and define a schema, so it throws errors, in case docs are inserted/updated that violate a schema. Using this would have thrown, that questionId is missing on insert.
I have tried dozens of solutions, and none of these worked and most of them are deprecated.
I have a collection with documents like this:
_id: 5d99ef3285c93711828cd15d
code: 1234
name: "Foo"
surname: "Bar"
address: "That street"
phone: 1234567
I would like to insert new document only if there isn't any document with the same code.
My last try was this:
const result = await db.collection('users').findOneAndUpdate(
{ code: user.code },
{
$setOnInsert: user,
},
{
upsert: true,
}
);
but I get E11000 duplicate key error collection...
updateOne() returns the same error; update() is deprecated...
So, how to add only new document and get the result (true if document has been added or false if it already exists)?
Thank you.
As far as my knowledge is,
with $set and $setOnInsert, we can not update/insert the same field.
i.e. $set and $setOnInsert should be mutually exclusive.
It works if the document is being updated, but throws an exception if document is being inserted.
In case of update, $setOnInsert will be ignored.
In case of insertion, both will be executed.
I think the solution would be,
use returnNewDocument and have one field in the schema isUpdated defaults to false.
Note:
make sure whenever you use "insert" operation on the collection, you don't add isUpdated which will be set to false then or set it to false.
form a query like
db.collection('users').findOneAndUpdate(
{ code: user.code },
{
$set: user, // which has user.isUpdated set to true
},
{
upsert: true,
returnNewDocument: false, // (by default it is false only)
}
);
With this logic,
So let's go step by step,
If the document doc1 is not present, it will be inserted, and mongo will return the response null. You will know, it is Inserted.
If the document doc2 is present(considering this logic is not applied on the previously inserted document doc2 before and isUpdated field is not present in doc2), it will execute $set so in returned cursor, this field not present i.e. undefined, so you know from this, it is updated.
let's say we fire the same query for doc1 again (which is present and we have applied our new logic), then there are two cases
a. it will be updated and in the cursor, we have isUpdated equal to false.
b. it will be updated and in the cursor, we have isUpdated equal to true.
In both case you know it is Updated
I think this approach should solve your problem.
Please share if this helps you, or you find any other solution.
UPDATE
ACTUALLY
You dont even need another field isUpdated, without this fiels this should work with the same logic.
i.e. If cursor is null then its inserted, if not null then its updated.
You can still run a query like this;
document = db.collection('users').findOne({code:userCode});
if(document == null){
//document doesn't exists so you can use insertOne
}
else{
// document exists, sou you can update
}
it won't be efficient but it'll do the work.
You can simply wrap the request with a try/catch block to catch the Error. Then return false when this exception occured.
You could use findOne to see if a user with that code exists first
const result = await db.collection('users')
.findOne({ code: user.code });
if( result ){
return res
.status(400)
.json({ errors: [{ msg: 'User already exists' }] });
}
//create
user = new User({
code = code,
name = name,
foo = foo
)}
//save
user.save();
res.json(user);
Try this one
db.collection("users").findOne({ code: user.code }, (err, data) => {
if (data) {
return res.send(false);
} else {
// a document
var user = new User({
code: code,
name: "Foo",
surname: "Bar",
address: "That street",
phone: 1234568
});
// save model to database
user.save(function(err, book) {
if (err) return console.error(err);
return res.send(true);
});
}
});
Users.findOneAndUpdate({code:user.code}, {upsert: true, new: true, setDefaultsOnInsert: true }, function(error, result) { if (error) return; // do something with the document }).
I think it would work. Let us know if you have any questions.
I'm writing my service to update a row using sequelize for PostGres. When I try out my query using a PSequel it works fine:
UPDATE "test_table" SET "test_col"=NULL WHERE "id"= '2'
But using sequelize it throws a 500 error:
db.TestTable.update({ testCol: NULL }, { where: { id: id } })
.then((count) => {
if (count) {
return count;
}
});
My model does allowNull which I believe is what allows null values to be the default as well as set:
testCol: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
field: 'test_col'
},
Any other value but NULL works as expected. Is there a different method for setting null values?
From the looks of it, I think your issue is that you are using SQL's syntax for a null value ('NULL') where you should be using JS syntax ('null').
db.TestTable.update({ testCol: null }, { where: { id: id } })
.then((count) => {
if (count) {
return count;
}
});
should work.
Have you checked a more detailed error message in logs? I'd suggest you to add a promise catching error and then update your question.
For now, my guess is that you created your connection with omitNull: true. Call an update function with just one null property probably is the reason of error 500 because it'll generate a incomplete UPDATE command (without SET).
Try to set omitNull: false or, if you cannot do this test, try to update this way:
db.TestTable.testCol = null;
db.TestTable.save(['testCol']);
More info here.
am trying to do a ConditionExpression in a DynamoDB put to check whether a stored boolean is true (in this example, whether the user is already verified don't run the put), i'm using the javascript DocumentClient SDK (thanks to #shimon-tolts), the code looks like:
var query = {
TableName: tableName,
Item: {
email: email,
verified: false,
verifyToken: token
},
ConditionExpression: 'attribute_exists(email) AND verified = :bool',
ExpressionAttributeValues: {
":bool":"false"
}
};
dynamodb.put(query, function(err, data){
if (err) return fn(err)
fn(null, data);
});
Which doesn't work, it fails the condition check no matter what the call.
Pretty much what I need (in pseudocode):
IF email already exists AND verified equals false
THEN allow PUT
IF email already exists AND verified equals true
THEN don't allow PUT
IF email does not exist
THEN allow PUT
Any ideas?
I suggest using DocumentClient as it works with javascript objects.
To do a condition expression you have to specify the ExpressionAttributeNames and ExpressionAttributeValues for example::
ConditionExpression: "#yr <> :yyyy and title <> :t",
ExpressionAttributeNames:{"#yr":"year"},
ExpressionAttributeValues:{
":yyyy":year,
":t":title
}
You can see more examples here and read more here
I finally got this to work after figuring out the right ExpressionAttributeValues:
dclient.scan(TableName='bix-workflow-images',
FilterExpression="wgs = :t or attribute_not_exists(wgs)",
ExpressionAttributeValues={':t':{'BOOL':True}})
I am stumbling about this because I have a similar problem and although this is a year old, for me it looks like your boolean shouldn't be a string:
ExpressionAttributeValues: {
":bool": "false"
}
Instead:
ExpressionAttributeValues: {
":bool": false
}
Have you tried it that way?
Following code gives me an exception in node js saying: "need to remove or update"
var args = {
query: { _id: _id },
update: { $set: data },
new: true,
remove: false
};
db.collection(COLLECTION.INVENTORY_LOCATION)
.findAndModify(args, function (err, results) {
if (err) {
return callback(err);
} else {
console.log(results);
callback(null, results);
}
});
Not able to figure out the issue as I have specified the update operation.
The syntax is different in the node driver than for the shell, which is the syntax you are using.
db.collection("collection_name").findAndModify(
{ _id: _id }, // query
[], // represents a sort order if multiple matches
{ $set: data }, // update statement
{ new: true }, // options - new to return the modified document
function(err,doc) {
}
);
There is a separate function for .findAndRemove()
As the documentation for the remove parameter of the findAndModify function states:
remove: <boolean>:
Must specify either the remove or the update field. Removes the
document specified in the query field. Set this to true to remove the
selected document . The default is false.
The default value is false so you don't have to provide it at all.
I believe the issue is that you are supplying both update and remove parameters. Try removing the remove parameter.