Temporary CouchDB View using Node module Nano - node.js

Nano doesn't provide documentation for temporary views, is there any undocumented method? Failing that, how would you advise somebody execute a temporary view using a nano-like syntax. Currently I am attempting to create the view as _view/guid, query it, return the results, and then delete it from the collection:
function generateToken() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}
var db = nano.use('db'),
fn = 'function(doc){ emit(doc); }',
token = generateToken(),
id = '_design/' + token;
db.insert({ views: { view: { map: fn } } }, id, function(){
db.view(token, 'view', function (err, results) {
db.get(id, function (err, view) {
console.log(results);
db.destroy(id, view._rev);
});
});
});
I assume this is inoptimal with the temporary view functionality built into couch core.
I'm aware of the temporary-view caveats, however I do believe I have a genuine usage case.

The temporary view API is described in the official CouchDB documentation: http://docs.couchdb.org/en/latest/api/database/temp-views.html#post--db-_temp_view

Open up futon and see what calls it does to the couchDB api ?
Edit: went and did the above
Futon does a post to SVRNAME/DBNAME/_temp_view?limit=11&descending=true
request payload {language: "javascript" map: function(doc) { emit(null, doc.id);}
and you must be logged in as an admin.
Hope that helps

I think you could do this through Nano using nano.request() (or nano.dinosaur()). https://github.com/dscape/nano#nanorequestopts-callback

Related

Create REST full service using Node js

I would like to build a node application using REST, need to read data from readymade api and store it in class for temp, and then save it to MySQL. Can anyone have any idea about this?
This is a very simple job.
Let's consider Typescript, but you can achieve the same result with JavaScript. I'll be using node-fetch as an example of the rest API library. Do note that the code might not be syntactically correct.
First: Create interfaces/classes that reflect the data you will receive from the REST API
interface Food {
id: number,
name: string,
...
}
Second:
Create a Repository
Create a class Repository which you will use to communicate with the rest API
class Repository {
async function getFoods(...args): List<Food> {
let foods = await fetch({url: "url"});
return foods;
}
async function addFood(food: Food): Response {
let response = await fetch({
url: "url-to-add-food",
method: "post",
data: JSON.stringify(food)
});
}
}
Third:
Use the repository to fetch the data and use conventional methods to save it to a MySQL database
let foods = await repository.getFoods();
foods.forEach(food => {
connection.query('INSERT INTO foods SET ?', food,
function (err, resp) {
if (err) throw err;
}
);
});

How to access manually created index in pouchdb find

I am pretty new to pouchDB and couchDB. I've trying to use pouchdb find but having some problems.
I have created a view "test" and source -
function(doc) {
emit(doc.name, doc.occupation);
}
and when i run this -
localDB.query('test/test').then(function (res) {
console.log(res);
}).catch(function (err) {
console.log(err);
});
Everything works as expected.
But when i try pouchdb find -
localDB.find({
selector: {name: 'kittens'}
}).then(function (result) {
console.log(result);
}).catch(function (err) {
console.log(err);
});
I got following error -
Error: couldn't find a usable index. try creating an index on: name.
If i create index by
localDB.createIndex({
index: {
fields: ['name']
}
});
only then pouchdb find code works. But when i manually created an index (shown in image above) then it doesn't.
Any help is appreciated. Thanks in advance.
pouchdb-find uses the new "Mango" query language, which is different from map/reduce. Mango is only supported in CouchDB 2.0+ and PouchDB Server, not CouchDB 1.x.
So at this time you will need to either use CouchDB 2.0 or PouchDB Server with pouchdb-find if you want it to work on both the client and the server, or you will need to use regular map/reduce instead and avoid pouchdb-find.

Azure mobile apps CRUD operations on SQL table (node.js backend)

This is my first post here so please don't get mad if my formatting is a bit off ;-)
I'm trying to develop a backend solution using Azure mobile apps and node.js for server side scripts. It is a steep curve as I am new to javaScript and node.js coming from the embedded world. What I have made is a custom API that can add users to a MSSQL table, which is working fine using the tables object. However, I also need to be able to delete users from the same table. My code for adding a user is:
var userTable = req.azureMobile.tables('MyfUserInfo');
item.id = uuid.v4();
userTable.insert(item).then( function (){
console.log("inserted data");
res.status(200).send(item);
});
It works. The Azure node.js documentation is really not in good shape and I keep searching for good example on how to do simple things. Pretty annoying and time consuming.
The SDK documentation on delete operations says it works the same way as read, but that is not true. Or I am dumb as a wet door. My code for deleting looks like this - it results in exception
query = queries.create('MyfUserInfo')
.where({ id: results[i].id });
userTable.delete(query).then( function(delet){
console.log("deleted id ", delet);
});
I have also tried this and no success either
userTable.where({ id: item.id }).read()
.then( function(results) {
if (results.length > 0)
{
for (var i = 0; i < results.length; i++)
{
userTable.delete(results[i].id);
});
}
}
Can somebody please point me in the right direction on the correct syntax for this and explain why it has to be so difficult doing basic stuff here ;-) It seems like there are many ways of doing the exact same thing, which really confuses me.
Thanks alot
Martin
You could issue SQL in your api
var api = {
get: (request, response, next) => {
var query = {
sql: 'UPDATE TodoItem SET complete=#completed',
parameters: [
{ name: 'completed', value: request.params.completed }
]
};
request.azureMobile.data.execute(query)
.then(function (results) {
response.json(results);
});
}};
module.exports = api;
That is from their sample on GitHub
Here is the full list of samples to take a look at
Why are you doing a custom API for a table? Just define the table within the tables directory and add any custom authorization / authentication.

Couchdb using nano , how to write search query

I am facing problem using couchdb. I am using nano module for this in nodejs. How can I implement search like match for user name and password. I tried this
body.rows.forEach(function(row) {
if(row.doc._id==user_id && row.doc.password==password){
found = true;
data = row;
}
});
but this is slow process
I found solution for search using key value in couch db using nano.
First you have to create design document and view (and implement
logic in that) then use them.
exports.testwhere = function (req, res) {
var db = nano.use('ionic');
db.insert({
"views": {
"by_email_and_password": {
"map": function (doc) {
emit([doc.email, doc.password], doc);
}
}
}
}, '_design/users', function (error, response) {
console.log("yay");
});
}
exports.testsearch = function (req, res) {
var db =
nano.use('ionic');
db.view('users', 'by_email_and_password', {
key: ["a#g.com", "aaa123"], include_docs: true
}, function (err, res) {
if (!err) {
console.log("Result " + JSON.stringify(res));
}
else {
console.log(err);
}
});
}
Your code body.rows.forEach ... is a map function (it iterates over every row) which executes a filter function if(row.doc._id==user_id ... to a row. Thats what CouchDB views do - exactly the same.
but this is slow process
True. Because of that CouchDB creates an index (a B-Tree that is a file inside CouchDB's database directory) and keeps this index up-to-date. The performance advantage for every request is that the result will be taken from the already prepared index instead of a just-in-time calculation as in your example.
The CouchDB view map function could look like:
function(doc) {
emit([doc._id,doc.password], null)
}
The key of every row is [:username,:password] and the value is null. If you request
/:db/:ddoc/_view/:name?key=[":username",":password"]
you will get the row immediately. Append a &include_docs=true and you will also get the whole doc appended to the row (alternatively you could emit a partial of the doc as value instead of null)
handling user accounts in CouchDB
User accounts and especially passwords are confidential data. CouchDB has the built-in _users db for it. I will not go into the details of the access control specifics of that db but want to say Store user account data there!. If you need account data outside this db then interpret that docs as "public profiles" e.g. to let users discover and connect to each other.

Angular UI Client Side Pagination

I would like to enable pagination and I'm torn between client side and server side pagination. In the long term (more data) it is probably better to do server side pagination, but I haven't found a good tutorial on it.
I use Angular/Express/Mongo. I have the Boostrap UI in use, and would like to use their pagination directive for pagination. I have read some articels on how to kind of do it, but they are outdated and I cannot get it to work. http://fdietz.github.io/recipes-with-angular-js/common-user-interface-patterns/paginating-through-client-side-data.html
Could anybody help me get that example to work with Bootstrap UI for Angular?
If you have a set number of items per page, you could do it this way :
Define an angular service to query the data on your server.
.factory('YourPaginationService', ['$resource',
function($resource) {
return $resource('baseUrl/page/:pageNo', {
pageNo: '#pageNo'
});
}
]);
Call it via the angular controller. Don't forget to inject your service, either globally or in the controller.
$scope.paginationController = function($scope, YourPaginationService) {
$scope.currentPage = 1;
$scope.setPage = function (pageNo) {
$scope.currentPage = pageNo;
YourPaginationService.query({
pageNo: '$scope.currentPage'
});
};
};
On express 4 (if you have it), set up your route.
app.route('/articles/page/:pageNo')
.get(data.listWithPagination) //random function name
Then you need to wire that function with the desired Mongo request in your Node controller. If you have Mongoose, it works like this :
exports.listWithPagination = function(req, res) {
var pageLimit = x; //Your hardcoded page limit
var skipValue = req.params.pageNo*pageLimit;
YourModel.find() //Your Mongoose model here, if you use Mongoose.
.skip(skipValue)
.limit(pageLimit)
.exec(function(err, data) {
if (err) {
return res.send(400, {
message: getErrorMessage(err)
});
} else {
res.jsonp(data);
}
});
};
That's how I would do it on a typical MEAN stack. If you're working with different libraries/technologies, you might need to adapt a few things.

Resources