Skip to content
Browse files

added full text search

  • Loading branch information...
1 parent 5c5fb5c commit ceb9b32a09dec3a52956bc9c631b68487b34bf23 Alex Young committed Mar 28, 2011
Showing with 105 additions and 2 deletions.
  1. +12 −0 Jakefile.js
  2. +16 −1 app.js
  3. +15 −0 models.js
  4. +48 −1 public/javascripts/application.js
  5. +6 −0 public/stylesheets/style.css
  6. +5 −0 public/stylesheets/style.styl
  7. +3 −0 views/layout.jade
View
12 Jakefile.js
@@ -0,0 +1,12 @@
+
+desc('Saves all documents to generate keywords');
+task('index', [], function() {
+ app = require('./app');
+
+ app.Document.find({}, function(err, documents) {
+ documents.forEach(function(d) {
+ console.log(d._id);
+ d.save();
+ });
+ });
+});
View
17 app.js
@@ -207,7 +207,7 @@ app.get('/documents/titles.json', loadUser, function(req, res) {
[], { sort: ['title', 'descending'] },
function(err, documents) {
res.send(documents.map(function(d) {
- return { title: d.title, id: d.id };
+ return { title: d.title, _id: d._id };
}));
});
});
@@ -380,6 +380,21 @@ app.del('/sessions', loadUser, function(req, res) {
res.redirect('/sessions/new');
});
+// Search
+app.post('/search.:format?', loadUser, function(req, res) {
+ Document.find({ user_id: req.currentUser.id, keywords: req.body.s ? req.body.s : null },
+ [], { sort: ['title', 'descending'] },
+ function(err, documents) {
+ switch (req.params.format) {
+ case 'json':
+ res.send(documents.map(function(d) {
+ return { title: d.title, _id: d._id };
+ }));
+ break;
+ }
+ });
+});
+
if (!module.parent) {
app.listen(3000);
console.log('Express server listening on port %d, environment: %s', app.address().port, app.settings.env)
View
15 models.js
@@ -3,6 +3,15 @@ var crypto = require('crypto'),
User,
LoginToken;
+function extractKeywords(text) {
+ if (!text) return [];
+
+ return text.
+ split(/\s+/).
+ filter(function(v) { return v.length > 2; }).
+ filter(function(v, i, a) { return a.lastIndexOf(v) === i; });
+}
+
function defineModels(mongoose, fn) {
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
@@ -14,6 +23,7 @@ function defineModels(mongoose, fn) {
'title': { type: String, index: true },
'data': String,
'tags': [String],
+ 'keywords': [String],
'user_id': ObjectId
});
@@ -22,6 +32,11 @@ function defineModels(mongoose, fn) {
return this._id.toHexString();
});
+ Document.pre('save', function(next) {
+ this.keywords = extractKeywords(this.data);
+ next();
+ });
+
/**
* Model: User
*/
View
49 public/javascripts/application.js
@@ -121,7 +121,7 @@
$('#create-document').click(function(e) {
$.post('/documents.json', { d: { data: '', title: 'Untitled Document' } }, function(new_doc) {
- $('#document-list').append('<li><a id="document-title-' + new_doc._id + '" href="/documents/' + new_doc._id + '">' + new_doc.title + '</a></li>');
+ showDocuments([new_doc]);
$('#document-title-' + new_doc._id).click();
});
e.preventDefault();
@@ -152,6 +152,53 @@
}, 5000);
$('.flash').click(hideFlashMessages);
+ // Search bar
+ function showDocuments(results) {
+ for (var i = 0; i < results.length; i++) {
+ $('#document-list').append('<li><a id="document-title-' + results[i]._id + '" href="/documents/' + results[i]._id + '">' + results[i].title + '</a></li>');
+ }
+ }
+
+ function search(value) {
+ $.post('/search.json', { s: value }, function(results) {
+ $('#document-list').html('');
+ $('#document-list').append('<li><a id="show-all" href="#">Show All</a></li>');
+
+ if (results.length === 0) {
+ alert('No results found');
+ } else {
+ showDocuments(results);
+ }
+ }, 'json');
+ }
+
+ $('input[name="s"]').focus(function() {
+ var element = $(this);
+ if (element.val() === 'Search')
+ element.val('');
+ });
+
+ $('input[name="s"]').blur(function() {
+ var element = $(this);
+ if (element.val().length === 0)
+ element.val('Search');
+ });
+
+ $('form.search').submit(function(e) {
+ search($('input[name="s"]').val());
+ e.preventDefault();
+ });
+
+ $('#show-all').live('click', function(e) {
+ $.get('/documents/titles.json', function(results) {
+ $('#document-list').html('');
+ showDocuments(results);
+ if (results.length > 0)
+ $('#document-title-' + results[0]._id).click();
+ });
+ e.preventDefault();
+ });
+
$(window).resize(resize);
$(window).focus(resize);
resize();
View
6 public/stylesheets/style.css
@@ -246,3 +246,9 @@ form.users input[type=submit] {
margin-left: 140px;
clear: both;
}
+form.search {
+ margin-right: 10px;
+}
+#show-all {
+ color: #999;
+}
View
5 public/stylesheets/style.styl
@@ -260,3 +260,8 @@ form.users input[type=submit]
margin-left 140px
clear both
+form.search
+ margin-right 10px
+
+#show-all
+ color medium-grey
View
3 views/layout.jade
@@ -17,6 +17,9 @@ html
- if (typeof currentUser !== 'undefined')
li.right
a#logout(href='/sessions') Log Out
+ li.right
+ form.search(action='/search')
+ input(name='s', value='Search')
!{flashMessages}
!= body
script(type='text/javascript', src='/javascripts/application.js')

0 comments on commit ceb9b32

Please sign in to comment.
Something went wrong with that request. Please try again.