From d4248a553a3a4743b96deeaebf47325735f3e5b5 Mon Sep 17 00:00:00 2001 From: Michael Bosworth Date: Fri, 15 Mar 2013 21:12:01 -0500 Subject: [PATCH 1/2] search with express and mongodb --- .../search-with-express-and-mongodb.markdown | 70 ++++++++++++++++++ .../compound-match-route.js | 23 ++++++ .../search-with-express-and-mongodb/data.json | 26 +++++++ .../express.js | 43 +++++++++++ .../search-with-express-and-mongodb/import.js | 35 +++++++++ .../search-with-express-and-mongodb/john.json | 9 +++ .../search-with-express-and-mongodb/mil.png | Bin 0 -> 45975 bytes .../search-with-express-and-mongodb/regex.js | 7 ++ .../single-match-route.js | 15 ++++ authors/Michael Bosworth.markdown | 6 ++ 10 files changed, 234 insertions(+) create mode 100644 articles/search-with-express-and-mongodb.markdown create mode 100644 articles/search-with-express-and-mongodb/compound-match-route.js create mode 100644 articles/search-with-express-and-mongodb/data.json create mode 100644 articles/search-with-express-and-mongodb/express.js create mode 100644 articles/search-with-express-and-mongodb/import.js create mode 100644 articles/search-with-express-and-mongodb/john.json create mode 100644 articles/search-with-express-and-mongodb/mil.png create mode 100644 articles/search-with-express-and-mongodb/regex.js create mode 100644 articles/search-with-express-and-mongodb/single-match-route.js create mode 100644 authors/Michael Bosworth.markdown diff --git a/articles/search-with-express-and-mongodb.markdown b/articles/search-with-express-and-mongodb.markdown new file mode 100644 index 0000000..9c8af17 --- /dev/null +++ b/articles/search-with-express-and-mongodb.markdown @@ -0,0 +1,70 @@ +Title: Powerful Search with Express and MongoDB +Author: Michael Bosworth +Date: Thu Mar 15 2013 21:28:42 GMT+0000 (UTC) +Node: v0.8.22 + +There are many ways to implement search and usually there is a specific need that you trying to meet. This may not be the search you are looking for, but it is a powerful one to leverage if ever the need arise! I'm talking about compounding search terms to match documents stored in [mongoDB][]. My use case is an employee directory. I don't know the persons name, but I should be able to type the persons team and office location and be able to narrow it down. Let's get started! + +###Sample Data### + +For this example, we will use a very simple data set. We will process this data and insert it into mongo. + + + +###Building A Index Attribute### + +To accomplish a compound search we are going to leverage [mongoDB][]'s support for regex. Since there is no easy way match a pattern against all the attributes in a document, we will flatten the data into a index attribute and test for matches there. For simplicity, I am using the [mongojs][] node module. To see where this code lives in the context of Express visit the [example project][]. + + + +Once the import has run, the {"first":"John"} document in mongo should look like this. Notice the index attribute has contactinated all of John's information. + + + +###Express### + +Now that our data is in monogoDB, we create a simple express server that will accept and process our query for data. For now, our route just returns all the data from the employees collection. Let's incoporate some regex and make it better. + + + +###Singular Matching### + +To start, we want to take the term that comes in from the request and match that term against the index string of each document and return the results. All this requries is a minor tweak in our route. The Regex pattern is simple. Match the whole term passed. Match it globally ("g") and be INsensitive to case ("i"). + + + +This gives us some pretty powerful results. We can search for any attribute of the document and get a match. We can even use partial words and get a match! You can see how powerful this would be provided a rich realtime front end. Maybe we will tackle that in a different post. + + + +###Compound Matching### + +We are getting close. Let's take what we've built and allow for multiple terms to be matched. For this, we need a delimiter, or something to denote from the query when a new term is starting or ending. Then we know how to parse it. Because I want users to use english-like sentences in searching, I'm just going to user a space (" "). + +Before we tweak our route again, we need a function to build our RegEx patterns. We need this function to be a little bit more robust than our single pattern match and strip white space (in the case of a double space). + + + +Before we tweak our route, we need to learn something about MongoDB. While Mongo querys are written in JSON, Mongo supports several custom operators for performing more advanced queries. For a list of those checkout the [Mongo docs][]. We are going to use the $all operator. This operator accepts and array of queries and ALL OF THEM have to be true in order for it to be included in the result. We will leverage this to build and array of, you guessed it, Regex patterns and match them against the index string. + + + +Search is at a whole new level. The nice thing about regex is that I can be lazy. I can just search for "mil" and narrow my results down to two employees. If I query "mil hum", short of course for employees working in Milwaukee's Human Resources department, then I narrow my result down to one and I don't have to know the persons name. Also note that we can search for employees based on the phone or email. The algoritm gives us freedom to query from any angle. + +###Concerns### + +I'm sure red flags went off for you around the data import section. "Redundancy!", you cried! Yes, admit it, I'm not making good use of the resources on the hard disk. You'll have to weigh the pros and cons based on how big your data set is. And who knows, maybe there is a better way to get the same results. + +Enjoy! + +__Boz__. + +[git]: http://git-scm.com/ +[node]: http://nodejs.org +[npm]: http://npmjs.org/ +[express]: http://github.com/visionmedia/express +[mongoDB]: http://www.mongodb.org +[Express and MongoDB]: /express-and-mongodb +[mongojs]: https://github.com/gett/mongojs.git +[example project]: https://github.com/bozzltron/search-with-express-and-mongodb +[Mongo docs]:http://docs.mongodb.org/manual/ \ No newline at end of file diff --git a/articles/search-with-express-and-mongodb/compound-match-route.js b/articles/search-with-express-and-mongodb/compound-match-route.js new file mode 100644 index 0000000..97f98b6 --- /dev/null +++ b/articles/search-with-express-and-mongodb/compound-match-route.js @@ -0,0 +1,23 @@ +app.get('/query/:term', function(req, res){ + + var term = req.params.term; + + // Break out all the words + var words = req.params.term.split(" "); + var patterns = []; + + // Create case insensitve patterns for each word + words.forEach(function(item){ + patterns.push(caseInsensitive(item)); + }); + + db.employees.find({index : {$all: patterns }}, function(err, results) { + if( err || !results) { + res.json([]); + } else { + res.json(results); + } + }); + + +}); \ No newline at end of file diff --git a/articles/search-with-express-and-mongodb/data.json b/articles/search-with-express-and-mongodb/data.json new file mode 100644 index 0000000..b5ff94d --- /dev/null +++ b/articles/search-with-express-and-mongodb/data.json @@ -0,0 +1,26 @@ +[ + { + "first":"John", + "last":"Doe", + "office":"Toronto", + "team":"Marketing", + "phone":"555-203-3002", + "email": "john@company.com" + }, + { + "first":"Jane", + "last":"Doe", + "office":"Milwaukee", + "team":"Human Resources", + "phone":"555-203-3007", + "email": "jane@company.com" + }, + { + "first":"Chuck", + "last":"Smith", + "office":"Milwaukee", + "team":"Development", + "phone":"555-203-3003", + "email": "chuck@company.com" + }, +] \ No newline at end of file diff --git a/articles/search-with-express-and-mongodb/express.js b/articles/search-with-express-and-mongodb/express.js new file mode 100644 index 0000000..b04fbca --- /dev/null +++ b/articles/search-with-express-and-mongodb/express.js @@ -0,0 +1,43 @@ + +/** + * Module dependencies. + */ + +var express = require('express') + , http = require('http'); + +var app = express(); + + // Mongo setup +var databaseUrl = "company"; +var collections = ["employees"] +var db = require("mongojs").connect(databaseUrl, collections); + +app.configure(function(){ + app.set('port', process.env.PORT || 3000); + app.use(express.bodyParser()); + app.use(express.methodOverride()); + app.use(app.router); +}); + +// Import the data +require('./import')(db); + +app.get('/query/:term', function(req, res){ + + var term = req.params.term; + + db.employees.find({}, function(err, results) { + if( err || !results) { + res.json([]); + } else { + res.json(results); + } + }); + + +}); + +http.createServer(app).listen(app.get('port'), function(){ + console.log("Express server listening on port " + app.get('port')); +}); \ No newline at end of file diff --git a/articles/search-with-express-and-mongodb/import.js b/articles/search-with-express-and-mongodb/import.js new file mode 100644 index 0000000..2617e59 --- /dev/null +++ b/articles/search-with-express-and-mongodb/import.js @@ -0,0 +1,35 @@ +// A function for building a search index collection for mongodb +function processData(data, db) { + + // Iterate over raw data objects + data.forEach(function(item){ + + // Instantiate our index string + var index = ""; + + // Iterate over the object keys + for (var key in item) { + if (item.hasOwnProperty(key)) { + var obj = item[key]; + + // append the value to the index + index += item[key]; + + } + } + + // Add the index attribute to the object + item.index = index; + + }); + + // Once all the data is processed lets insert it into mongo + + // Clear any existing data + db.employees.drop(); + + // Because we are passing an array of objects, + // mongo knows to create a new document for each one + db.employees.insert(data); + +} \ No newline at end of file diff --git a/articles/search-with-express-and-mongodb/john.json b/articles/search-with-express-and-mongodb/john.json new file mode 100644 index 0000000..4d2620b --- /dev/null +++ b/articles/search-with-express-and-mongodb/john.json @@ -0,0 +1,9 @@ + { + "first":"John", + "last":"Doe", + "office":"Toronto", + "team":"Marketing", + "phone":"555-203-3002", + "email": "john@company.com", + "index": "JohnDoeTorontoMarketing555-203-3002john@company.com" + } \ No newline at end of file diff --git a/articles/search-with-express-and-mongodb/mil.png b/articles/search-with-express-and-mongodb/mil.png new file mode 100644 index 0000000000000000000000000000000000000000..326311f1b1baae4d058c63420c8f13988aeab19b GIT binary patch literal 45975 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
{2PR2vAn&;MPcZc@#}R- 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 YYMC{R)8OK9y@0(WL}f)Pg!TOY5Aprmwg3PC literal 0 HcmV?d00001 diff --git a/articles/search-with-express-and-mongodb/regex.js b/articles/search-with-express-and-mongodb/regex.js new file mode 100644 index 0000000..afd1718 --- /dev/null +++ b/articles/search-with-express-and-mongodb/regex.js @@ -0,0 +1,7 @@ +// Facilitates queries on mongodb +function caseInsensitive(keyword){ + // Trim + keyword = keyword.replace(/^\s+|\s+$/g, ''); + + return new RegExp(keyword, 'gi'); +} diff --git a/articles/search-with-express-and-mongodb/single-match-route.js b/articles/search-with-express-and-mongodb/single-match-route.js new file mode 100644 index 0000000..0a67160 --- /dev/null +++ b/articles/search-with-express-and-mongodb/single-match-route.js @@ -0,0 +1,15 @@ +app.get('/query/:term', function(req, res){ + + var term = req.params.term; + var pattern = new RegExp(term, 'gi'); + + db.employees.find({index:pattern}, function(err, results) { + if( err || !results) { + res.json([]); + } else { + res.json(results); + } + }); + + +}); \ No newline at end of file diff --git a/authors/Michael Bosworth.markdown b/authors/Michael Bosworth.markdown new file mode 100644 index 0000000..f41cd1d --- /dev/null +++ b/authors/Michael Bosworth.markdown @@ -0,0 +1,6 @@ +Email: mtbosworth@gmail.com +Github: bozzltron +Twitter: bozzltron +Homepage: http://www.balancedscale.com + +A JavaScript developer and nodejs enthustiast. \ No newline at end of file From 66e9682100c5c756a463faf8a966de9ab39468eb Mon Sep 17 00:00:00 2001 From: Michael Bosworth Date: Fri, 15 Mar 2013 22:50:31 -0500 Subject: [PATCH 2/2] search with express and mongo review --- .../search-with-express-and-mongodb.markdown | 18 ++++++++++-------- .../mil_hum.png | Bin 0 -> 46613 bytes .../search-with-express-and-mongodb/regex.js | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 articles/search-with-express-and-mongodb/mil_hum.png diff --git a/articles/search-with-express-and-mongodb.markdown b/articles/search-with-express-and-mongodb.markdown index 9c8af17..3a8e29e 100644 --- a/articles/search-with-express-and-mongodb.markdown +++ b/articles/search-with-express-and-mongodb.markdown @@ -23,13 +23,13 @@ Once the import has run, the {"first":"John"} document in mongo should look like ###Express### -Now that our data is in monogoDB, we create a simple express server that will accept and process our query for data. For now, our route just returns all the data from the employees collection. Let's incoporate some regex and make it better. +Now that our data is in monogoDB, we create a simple express server that will accept and process our query. For now, our route returns all the data from the employees collection. ###Singular Matching### -To start, we want to take the term that comes in from the request and match that term against the index string of each document and return the results. All this requries is a minor tweak in our route. The Regex pattern is simple. Match the whole term passed. Match it globally ("g") and be INsensitive to case ("i"). +To make our query return meaningful data, we want to take the term that comes in from the request and match that term against the index string of each document and return the results. All this requires is a minor tweak in our route. The Regex pattern is simple. Match the whole term passed. Match it globally ("g") and be INsensitive to case ("i"). @@ -39,21 +39,23 @@ This gives us some pretty powerful results. We can search for any attribute of ###Compound Matching### -We are getting close. Let's take what we've built and allow for multiple terms to be matched. For this, we need a delimiter, or something to denote from the query when a new term is starting or ending. Then we know how to parse it. Because I want users to use english-like sentences in searching, I'm just going to user a space (" "). +We are getting close. Let's take what we've built and allow for multiple terms to be matched. For this, we need a delimiter, or something to denote from the query when a new term is starting or ending. Then we know how to parse it. Because I want users to use english-like sentences in searching, I'm just going to use a space (" "). -Before we tweak our route again, we need a function to build our RegEx patterns. We need this function to be a little bit more robust than our single pattern match and strip white space (in the case of a double space). +We are going to need to build a Regex pattern for each term that we parse, so lets make a function for building patterns. We need this function to be a little bit more robust than our single pattern match and strip white space (in the case of a double space). -Before we tweak our route, we need to learn something about MongoDB. While Mongo querys are written in JSON, Mongo supports several custom operators for performing more advanced queries. For a list of those checkout the [Mongo docs][]. We are going to use the $all operator. This operator accepts and array of queries and ALL OF THEM have to be true in order for it to be included in the result. We will leverage this to build and array of, you guessed it, Regex patterns and match them against the index string. +Before we tweak our route, we need to learn something about MongoDB. While Mongo querys are written in JSON, Mongo supports several custom operators for performing more advanced queries. For a list of those checkout the [Mongo docs][]. We are going to use the $all operator. This operator accepts an array of queries and ALL of them have to match a document in order for it to be included in the result. We will leverage this to build and array of, you guessed it, Regex patterns and match them against the index string. -Search is at a whole new level. The nice thing about regex is that I can be lazy. I can just search for "mil" and narrow my results down to two employees. If I query "mil hum", short of course for employees working in Milwaukee's Human Resources department, then I narrow my result down to one and I don't have to know the persons name. Also note that we can search for employees based on the phone or email. The algoritm gives us freedom to query from any angle. +Search is at a whole new level. The nice thing about regex is that I can be lazy. I can just search for "mil" and narrow my results down to two employees who work in Milwaukee. If I query "mil hum", short of course for employees working in Milwaukee's Human Resources department, then I narrow my result down to one and I don't have to know the persons name. Also note that we can search for employees based on the phone or email. The algoritm gives us freedom to query the data from any angle. + + ###Concerns### -I'm sure red flags went off for you around the data import section. "Redundancy!", you cried! Yes, admit it, I'm not making good use of the resources on the hard disk. You'll have to weigh the pros and cons based on how big your data set is. And who knows, maybe there is a better way to get the same results. +I'm sure red flags went off for you around the data import section. "Redundancy!", you cried! Yes, admit it, I'm not making good use of the resources on the hard disk. You'll have to weigh the pros and cons based on how big your data set is. And who knows, maybe there is a better way. Enjoy! @@ -67,4 +69,4 @@ __Boz__. [Express and MongoDB]: /express-and-mongodb [mongojs]: https://github.com/gett/mongojs.git [example project]: https://github.com/bozzltron/search-with-express-and-mongodb -[Mongo docs]:http://docs.mongodb.org/manual/ \ No newline at end of file +[Mongo docs]: http://docs.mongodb.org/manual/reference/operators/ \ No newline at end of file diff --git a/articles/search-with-express-and-mongodb/mil_hum.png b/articles/search-with-express-and-mongodb/mil_hum.png new file mode 100644 index 0000000000000000000000000000000000000000..73ff7a4b82ae8563a4c01f2088ce95c910464bc9 GIT binary patch literal 46613 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 literal 0 HcmV?d00001 diff --git a/articles/search-with-express-and-mongodb/regex.js b/articles/search-with-express-and-mongodb/regex.js index afd1718..310be6b 100644 --- a/articles/search-with-express-and-mongodb/regex.js +++ b/articles/search-with-express-and-mongodb/regex.js @@ -1,4 +1,4 @@ -// Facilitates queries on mongodb +// Build a regex pattern without whitespace function caseInsensitive(keyword){ // Trim keyword = keyword.replace(/^\s+|\s+$/g, '');