Browse Source

Added support for AND style queries. Updated test page to incorporate

new query support. Added TODO list. Cleaned up a few functions and
added some more clarifying comments.
master
Christopher Ramey 12 years ago
committed by cdramey
parent
commit
45508e74d6
  1. 16
      TODO
  2. 91
      test.html
  3. 49
      tidx.js

16
TODO

@ -0,0 +1,16 @@
Coming soon
===========
Better README
Clearer function comments
Maybe one day
=============
Larger/More extensive set of test data
Wildcard support
Stemming
Probably not
============
Ranged queries

91
test.html

@ -7,10 +7,27 @@
</style>
</head>
<body>
<input type="text" id="search" name="search" size="50" />
<input type="button" id="btn_search" value="Search" />
<br/><br/>
<textarea name="output" id="output" rows="10" cols="40"></textarea>
<table>
<tr>
<td><label for="or_search">Logical OR Search:</label></td>
<td><input type="text" id="or_search" name="search" size="50" /></td>
<td><input type="button" id="btn_or_search" value="Search"/></td>
</tr>
<tr>
<td><label for="and_search">Logical AND Search:</label></td>
<td><input type="text" id="and_search" name="search" size="50" /></td>
<td><input type="button" id="btn_and_search" value="Search" /></td>
</tr>
<tr>
<td>&nbsp;</td>
<td colspan="2">
<textarea name="output" id="output" rows="10" cols="45"></textarea>
</td>
</tr>
</table>
<br/>
<table>
<thead>
<tr>
@ -55,38 +72,52 @@
output.val(output.val() + 'indexed in ' + (new Date().getTime() - s) + "ms\n");
});
// Setup the search button
$('#btn_search').click(function(){
output.val(output.val() + 'Searching .. ');
var s = new Date().getTime();
var results = t.search($('#search').val());
output.val(output.val() + 'completed in ' + (new Date().getTime() - s) + "ms\n");
// Setup the search buttons
$('#btn_or_search').click(function(){
dosearch(false, $('#or_search').val());
});
var rtbl = $('#result_table').empty();
for(var idx in results){
var i = results[idx];
rtbl.append(
'<tr>' +
'<td>' + json[i]['id'] + '</td>' +
'<td>' + json[i]['name'] + '</td>' +
'<td>' + json[i]['email'] + '</td>' +
'<td>' + json[i]['city'] + '</td>' +
'<td>' + json[i]['state'] + '</td>' +
'<td>' + json[i]['country'] + '</td>' +
'<td>' + json[i]['rank'] + '</td>' +
'<td>' + json[i]['desc'] + '</td>' +
'</tr>'
);
}
$('#btn_and_search').click(function(){
dosearch(true, $('#and_search').val());
});
// Enter should work to search, too
$('#search').keydown(function(e){
if(e.which == 13){ $('#btn_search').click(); }
$('#or_search').keydown(function(e){
if(e.which == 13){ $('#btn_or_search').click(); }
});
$('#and_search').keydown(function(e){
if(e.which == 13){ $('#btn_and_search').click(); }
}).focus();
});
function dosearch(and_search, value){
var output = $('#output');
output.val(output.val() + 'Searching .. ');
var s = new Date().getTime();
var results = t.search(and_search, value);
output.val(output.val() + 'completed in ' + (new Date().getTime() - s) + "ms\n");
var rtbl = $('#result_table').empty();
for(var idx in results){
var i = results[idx];
rtbl.append(
'<tr>' +
'<td>' + json[i]['id'] + '</td>' +
'<td>' + json[i]['name'] + '</td>' +
'<td>' + json[i]['email'] + '</td>' +
'<td>' + json[i]['city'] + '</td>' +
'<td>' + json[i]['state'] + '</td>' +
'<td>' + json[i]['country'] + '</td>' +
'<td>' + json[i]['rank'] + '</td>' +
'<td>' + json[i]['desc'] + '</td>' +
'</tr>'
);
}
}
</script>
</body>
</html>

49
tidx.js

@ -7,11 +7,11 @@ var Tidx = function()
// regex used to find terms inside a value
this.v_rx = new RegExp('(:?[a-z_-]+)|(\\d*\\.\\d+)|(\\d+)', 'mg');
// regex used to break out terms with a search
// regex used to break out terms within a search
this.s_rx = new RegExp('(:?([a-z\\d-_]+):){0,1}(:?(:?"(.+?)")|([a-z_-]+)|(\\d*\\.\\d+)|(\\d+))', 'img')
// Adds data to index
// Indexes data inside this object.
this.index = function(tokenize, id, field, value)
{
var f;
@ -64,7 +64,7 @@ var Tidx = function()
// Conducts a global search for a string (value) globally,
// iterating through all fields.
this.gsearch = function(result, value)
this.gsearch = function(value, result)
{
// Refuse empty searches
if(value.length === 0){ return []; }
@ -75,10 +75,11 @@ var Tidx = function()
for(var f in this._index){
// Look for the specified search term
if(this._index[f][v] !== undefined){
// If it exists, add the result to r, adding in the weight
// If it exists, add the result to r, adding in the weight and count
for(var i in this._index[f][v]){
if(result[i] === undefined){ result[i] = 0; }
result[i] += this._index[f][v][i];
if(result[i] === undefined){ result[i] = {'w': 0, 'c': 0}; }
result[i]['w'] += this._index[f][v][i];
result[i]['c']++;
}
}
}
@ -86,7 +87,7 @@ var Tidx = function()
// Conducts a field specific search for a string (value)
this.fsearch = function(result, field, value)
this.fsearch = function(field, value, result)
{
var f;
switch(typeof field){
@ -104,19 +105,22 @@ var Tidx = function()
}
for(var i in this._index[f][v]){
if(result[i] === undefined){ result[i] = 0; }
result[i] += this._index[f][v][i];
if(result[i] === undefined){ result[i] = {'w': 0, 'c': 0}; }
result[i]['w'] += this._index[f][v][i];
result[i]['c']++;
}
};
// Multi-term searching function - this is what you should use to
// search with, returns an array of found ids ordered by weight
this.search = function(search)
// Multi-term searching function. This is what you should use
// to search with. If and_query is true, returned results
// must match every term. Otherwise, any ID matching any
// term is returned.
this.search = function(and_query, search)
{
var r = {};
var re;
var re, tc=0;
while((re = this.s_rx.exec(search)) !== null){
var field = re[2];
@ -130,21 +134,30 @@ var Tidx = function()
// Global term
if(field !== undefined && field.length !== 0){
this.fsearch(r, field, value);
this.fsearch(field, value, r);
} else {
this.gsearch(r, value);
this.gsearch(value, r);
}
tc++;
}
return this.sortresult(r);
return this.order(r, (and_query ? tc : 0));
};
this.sortresult = function(o)
// Orders the result of a query. Accepts an object as a result, and
// the minimum floor count. In the event of an AND query, floor should
// be quality to the number of search terms. Otherwise it should be zero.
this.order = function(result, floor)
{
var t = [];
for(var i in o){ t.push([i, o[i]]); }
for(var i in result){
if(floor == 0 || result[i]['c'] >= floor){
t.push([i, result[i]['w']]);
}
}
t.sort(function(a,b){ return b[1] - a[1]; });
var r = [];