How to create a website with a searchbar to query a mongo database? - mongodb

I have a large mongoDB database set up and am trying to create a website where a user can use a searchbar to query the database remotely and have the results posted on the site (strictly read-only).
I have experience with databases for data analysis, but have never created a website for querying results.
I'm don't have any experience with web development and don't know what platforms (PHP? node.js?) to use.
Thanks in advance.

There are the following steps to the problem:
Create the front-end, which will consist of HTML, CSS, and Javascript. Beginners often find it easiest to work with jQuery and jQuery UI, because they are well-documented and contain plugins for almost all possible scenarios (they should not, however, be used to create large complex applications!). Bootstrap or Foundation can help you with the HTML / CSS.
Create a (probably) JSON API, which the front-end can communicate with to submit searches and retrieve results. You could use PHP, Python, Ruby, or many other languages to do this. For a simple site like the one you're describing, it's more a matter of preference than anything else.
Translate the search request from the front-end into the MongoDB query APIs, and return the results through the API. You will use a MongoDB client library compatible with whatever language you have chosen.
Depending on your needs, you may be able to eliminate (2) by using an existing REST API for MongoDB.
Note that if you just want to make MongoDB data accessible via searching / charting, then you may be able to avoid coding altogether by leveraging SlamData, an open source project I contribute to. SlamData lets you use Google-style search (or more advanced SQL) to query MongoDB and get the results back in tabular or chart form.

I am doing such in nodejs.
In my server side app I have connection via mognoose like:
var mongoose = require('mongoose');
mongoose.connect('mongodb://yourhost/database');
Next you need to have your model to your database
var YourDBVarName = mongoose.model('collectionName', {
yourfields1 : type,
yourfields2 : type,
yourfields3 : type
...
});
Then I make GET for it
var express = require('express');
var app = express();
app.get('/dblisting', function(req,res){
YourDBVarName.find({ yourfieldsX: 'value'}, function(err, data) {
if(err) {
res.send(err.message);
}
else{
res.send(data);
});
});
Then simply you make some GET with $.ajax to yournodeserver.com/dblisting and in response you recive your collection filtered as in
{ yourfieldsX: 'value'}
Ofcourse you may do just {} so you get all your stored data.

SLee
If you want know about retrieving data from mongoDB, you can use my github https://github.com/parthaindia/CustomMongo .Use getByCondition() method which requires collection name and a Map . The Map can be your queries in form of key value pair,Key being the column name. I use this method when I write search Query for the web development. The java code gives you a Json. Write a Servlet to post your Json to WEB UI.
This is an example to show how to post the retrieved data using Js ,"server_base_url + /server/FetchData" would be your Service URL.The data you has to be appended to a table . Or a span ,depends on what you actually want.The below code appends data
function getdata() {
$.get(server_base_url + "/server/FetchData", {
}).done(function (data) {
$.each(data, function (index, value) {
alert("The Index" + index + "The Value" + value);
$("#11table1").append("<tr><td id='dynamicid1" + index + "'>" + value + "</td></tr>");
});
});
}
This function can be used for defining table
function defineTable() {
$("#mainDivID").text("").append("<div id='contpanel' class='contentpanel'>");
$("#contpanel").append("<div id='rowid11' class='row'>");
$("#rowid11").text("").append("<div id='row11table1' class='col-md-12'>");
$("#row11table1").text("").append('<br /><br /><center><h5 class="lg-title mb5" style="background-color:#428BCA;height:20px;color:#fff;padding-top:4px;"><b>Heading</b></h5></center>');
$("#row11table1").append("<div id='table11id1' class='table-responsive'>");
$("#table11id1").append("<table id='11table1' class='table table table-bordered mb30' >");
$("#11table1").append("<thead><tr><th>Index</th><th>Value</th></tr></thead>");
}

Related

Does JSONModel have $top and $skip like OData?

In my app I'm reading data from a JSON file and creating a model from it like this
var myModel = new sap.ui.model.JSONMOdel("pathToJson");
I have 300 values but I only want to read 50, is there a way to do that. I know I can use $top and $skip to select a specific set of values using OData. The API provides the function myModel.loadData() which contains a parameter oParameters but I don't know what I can pass in. Does anyone know if this possible?
The JSON model is a client-side model. This means that all the data is loaded at once with a single request. In the standard implementation, it has no methods for reading paged JSON contents (with top / skip or any other name you might give them).
You have said that you have a JSON file that you are loading. So such a paging does not even make sense from a technical point of view. This is because you cannot (easily) load a portion of a static file with client-only code (especially JSON, which is not valid if you are reading a fragment of it).
If you actually just want to store a segment of the file in the model, you can simply read the whole file with jQuery.ajax and then slice the array.
If you actually have a RESTful web service, then the paging mechanism should be part of this service (e..g it should have some path or query parameters for specifying the paging parameters). This service should return a valid JSON document for each call. On the client side, you can use such a service with the help of some functions (e.g. in the controller):
onInit: function () {
this.setModel(new JSONModel([])); // initially an emty array
},
//call this method when you want to read a page
onReadDataPage: function (iTop, iSkip) {
// use jQuery.ajax or jQuery.get to read a "page" of data; e.g.
jQuery.ajax({
url: "your service path",
data: {
top: iTop,
skip: iSkip || 0
},
success: this.onDataReceived.bind(this)
});
},
onDataReceived: function (aData) {
var oModel = this.getModel();
oModel.setData(oModel.getData().concat(aData);
}
If you want to use this in combination with a List with the growing feature, then you will need to create a new type of model - which is not trivial.

Meteor Method to send a public MongoDB document without publishing everything

new to meteor and mongo.
I have some JSON stored in mongo that I want to publicly expose via an obfuscated token without using something like:
//app/models/stuff.js
Stuff = new Mongo.Collection("stuff");
Meteor.publish("stuff", function (){
return Stuff.find();
});
//additionally, the client-side subscription
I only want to expose the files that the client directly requests via a URL routing parameter or some sort of client side identifier (like a textfield where you can type the code/token in)
e.g., http://website.com/view/abcdefghijklmnop
Anyone with knowledge of the link can type it in, and get the file. However, there should be no way to just get every file without being given every token.
I was wondering if this was the best way to accomplish the task:
//app/server/stuff.js
Meteor.methods({
getStuff: getStuff
});
function getStuff(stuffId) {
var result = Stuff.find({_id: stuffId});
return result;
}
then
//app/client/stuff.js
var json = Meteor.call('getStuff', 'abcdefghijklmnop');
Why not just publish the requested document?
Meteor.publish('stuff', function (id){
check(id, String);
return Stuff.find(id);
});

Transforming DB Collections in Meteor.publish

Hopefully this question is not too long but I am trying to include as much details as possible in what I did..
I am trying to figure out how to implement logic in Meteor.publish() that takes data from the DB, changes all the values in a column and makes the updated collection available for client-side subscription.
Specifically, I have a table that stores messages between users and the recipient is identified by his userId. I would like to replace the userId with his actual phone number which should be available in the Meteor.users table.
When I looked it up online I saw suggestions to use transform but my understanding is that it's not reactive.. I then learned about map but discovered that it returns an array which breaks the Meteor.publish() method. Finally I found something that uses forEach and self.added() and self.ready() so my code currently looks like this:
Meteor.publish("myMessages", function () {
var self = this;
Messages.find({
$or: [
{ senderId: this.userId },
{ recipientId: this.userId }
]
}).forEach(function(m) {
m.recipientId = Meteor.users.findOne({ _id: m.recipientId }).username;
console.log("adding msg to collection:");
console.log(m);
self.added("Messages", m._id, m);
});
self.ready();
});
The log messages look right and when Meteor restarts it prints all the messages from the DB related to the user where the recipient is replaced correctly with the phone number. However, on the client side when I try to run Messages.findOne(msgId) (with an id I verified exists by selecting it directly in mongo shell) I get undefined back and furthermore, running Messages.find() through developer tools in the browser returns undefined as well although I expected the messages that showed up in the logs to be available..
I feel that this is a basic use case but I am not able to make this work.. any help is appreciated!
"You can transform a collection on the server side like this:"
https://stackoverflow.com/a/18344597/4023641
It worked for me.
Unfortunately, changes in users collection will not update reactively these custom fields.

Angular JS: Full example of GET/POST/DELETE/PUT client for a REST/CRUD backend?

I've implemented a REST/CRUD backend by following this article as an example: http://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/ . I have MongoDB running locally, I'm not using MongoLabs.
I've followed the Google tutorial that uses ngResource and a Factory pattern and I have query (GET all items), get an item (GET), create an item (POST), and delete an item (DELETE) working. I'm having difficulty implementing PUT the way the backend API wants it -- a PUT to a URL that includes the id (.../foo/) and also includes the updated data.
I have this bit of code to define my services:
angular.module('realmenServices', ['ngResource']).
factory('RealMen', function($resource){
return $resource('http://localhost\\:3000/realmen/:entryId', {}, {
query: {method:'GET', params:{entryId:''}, isArray:true},
post: {method:'POST'},
update: {method:'PUT'},
remove: {method:'DELETE'}
});
I call the method from this controller code:
$scope.change = function() {
RealMen.update({entryId: $scope.entryId}, function() {
$location.path('/');
});
}
but when I call the update function, the URL does not include the ID value: it's only "/realmen", not "/realmen/ID".
I've tried various solutions involving adding a "RealMen.prototype.update", but still cannot get the entryId to show up on the URL. (It also looks like I'll have to build the JSON holding just the DB field values myself -- the POST operation does it for me automatically when creating a new entry, but there doesn't seem to be a data structure that only contains the field values when I'm viewing/editing a single entry).
Is there an example client app that uses all four verbs in the expected RESTful way?
I've also seen references to Restangular and another solution that overrides $save so that it can issue either a POST or PUT (http://kirkbushell.me/angular-js-using-ng-resource-in-a-more-restful-manner/). This technology seems to be changing so rapidly that there doesn't seem to be a good reference solution that folks can use as an example.
I'm the creator of Restangular.
You can take a look at this CRUD example to see how you can PUT/POST/GET elements without all that URL configuration and $resource configuration that you need to do. Besides it, you can then use nested resources without any configuration :).
Check out this plunkr example:
http://plnkr.co/edit/d6yDka?p=preview
You could also see the README and check the documentation here https://github.com/mgonto/restangular
If you need some feature that's not there, just create an issue. I usually add features asked within a week, as I also use this library for all my AngularJS projects :)
Hope it helps!
Because your update uses PUT method, {entryId: $scope.entryId} is considered as data, to tell angular generate from the PUT data, you need to add params: {entryId: '#entryId'} when you define your update, which means
return $resource('http://localhost\\:3000/realmen/:entryId', {}, {
query: {method:'GET', params:{entryId:''}, isArray:true},
post: {method:'POST'},
update: {method:'PUT', params: {entryId: '#entryId'}},
remove: {method:'DELETE'}
});
Fix: Was missing a closing curly brace on the update line.
You can implement this way
$resource('http://localhost\\:3000/realmen/:entryId', {entryId: '#entryId'}, {
UPDATE: {method: 'PUT', url: 'http://localhost\\:3000/realmen/:entryId' },
ACTION: {method: 'PUT', url: 'http://localhost\\:3000/realmen/:entryId/action' }
})
RealMen.query() //GET /realmen/
RealMen.save({entryId: 1},{post data}) // POST /realmen/1
RealMen.delete({entryId: 1}) //DELETE /realmen/1
//any optional method
RealMen.UPDATE({entryId:1}, {post data}) // PUT /realmen/1
//query string
RealMen.query({name:'john'}) //GET /realmen?name=john
Documentation:
https://docs.angularjs.org/api/ngResource/service/$resource
Hope it helps

node.js: expressjs with mongoose

I'm working on my first node.js / express / mongoose app and I'm facing a problem due to asynchronisation mechanism of node.js. It seems I do not do the thing correctly...
Here is the test route I defined using express:
app.get('/test', function(req, res){
var mod = mongoose.model('MyModel');
mod.find({},function(err, records){
records.forEach(function(record){
console.log('Record found:' + record.id);
// res.send('Thing retrieved:' + record.id);
});
});
});
When I issue a http://localhost/test, I'd like to get the list of records of type 'MyModel' in the response.
The code above is working fine but when it comes to returning this whole list to the client... it does not work (the commented res.send line) and only returned the first record.
I'm very new to node.js so I do not know if it's the good solution to embed several callback functions within the first callback function of app.get . How could I have the whole list returned ?
Any idea ?
What you should be doing is:
mod.find({},function(err, records){
res.writeHead(200, {'Content-Length': body.length});
records.forEach(function(record){
res.write('Thing retrieved:' + record.id);
});
});
Please always check the documentation as well:
http://nodejs.org/docs/v0.3.8/api/http.html#response.write
I missed that you was using express, the send function is part of express and extend's the serverResponse object of node (my bad).
but my answer still applies, express's send function sends the data using ServerResponse.end() so there for the socket get's closed and you cannot send data any more, using the write function uses the native function.
You may also want to call res.end() when the request is fully completed as some item's within express may be affected