我正在尝试在客户端计算机上实现基于全文的搜索功能。
我发现Lunr.js部分满足了我的要求,但它必须加载到像Apache这样的服务器上,然后才能完美运行。
在我的情况下,客户端计算机将不会安装任何服务器或数据库。目录中只有一堆静态HTML文件,一个索引文件接受来自搜索框的用户输入,该搜索框在这些静态HTML文件中搜索此字符串。
谷歌搜索显示我的项目中可能需要一些有趣的词语:innerHtml
,DOM
,iframes
和RegExp
。
请根据您的答案制定我的疑问。提前致谢
答案 0 :(得分:2)
我可以想到这样做的一种方法 - 您可以使用XMLHttpRequest获取本地文件。默认情况下不允许这样做,但例如可以使用以下参数启动chrome:
--allow-file-access-from-files
您必须浏览所有要查看的文件,并通过stripping html tags手动执行搜索并执行正则表达式,这应该不会很难。
我在chrome中测试了以下代码:
var xmlhttp = new XMLHttpRequest();
var url = "file:///your-file.html";
xmlhttp.open('GET', url, true);
xmlhttp.onerror = function(e) { console.log('Problems' + e); };
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState === 4 && xmlhttp.status === 0) {
console.log("Fetched: ");
console.log(xmlhttp.responseText);
}
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
// ....
}
else if (xmlhttp.readyState==4 && xmlhttp.status != 200) {
// ....
}
}
xmlhttp.send();
答案 1 :(得分:1)
尽管我没有尝试过以这种方式使用它,你可以查看jIO(Github)
jIO可用于跨多个存储管理和同步JSON文档(浏览器localstorage,webDav,xWiki,S3 ......)。存储可以编入索引,jIO自带查询模块,称为complexQueries,也可以单独使用。
如果您通过Ajax请求页面并提取页面的全文/ HTML,只需将其作为文档转储到jIO中。
有三种方法(jIO documentation中的所有示例):
1)使用普通本地存储和复杂查询
在jIO中为您想要搜索的每个文档创建一个文档。所以在设置你的jIO之后:
var mySearchFiles = JIO.newJio({
"type" : "local",
"username" : "whatever",
"application_name" : "fulltextsearch"
});
将完整的HTML /提取文本(localstorage大小限制...)添加为如下文档:
mySearchFiles.put({
"_id": "your_id",
"search_result_string": "page_title/page_filename",
"searchable_text": "your_text_to_be_searched_goes_here",
function (err, response) {
// console.log(response) =
// {
// "ok": true,
// "id": "your_id",
// }
}
);
使用_id
或其他自定义键作为搜索时从jIO返回的内容。
然后使用allDocs方法在您的jIO上运行复杂查询(here是一个用于解决复杂查询的示例页面):
// here you construct your basic query
var query_object = {
"query":{
"filter": {
// records from/to to be returned
"limit":[0,10],
// sort direction
"sort_on":[[search_result_string, "ascending"]],
// what fields to return
"select_list":[["search_result_string"]]
},
// wildchard
"wildcard_character":'%'
}
};
// build your query - if user entered the variable "search_term":
var search = "searchable_text: = %" + search_term + "%";
// add to query object
query_object.query.query = search;
// run the search
mySearchFiles.allDocs(
query_object,
function (err, response){
console.log(response);
}
);
这应该返回您想要的search_result_string
。我不知道搜索大文本的速度有多快,但如果需要,可以使用JSCC Parser Generator编写自己的搜索语法。
<强> 2。仅使用复杂查询
您可以使用ComplexQueries独立中使用的parse
,serialize
和query
方法。查看示例页面link as above,了解其工作原理。
基本上,您需要将要搜索的数据作为对象列表提供,并且必须序列化查询。然后打电话:
var result = jIO.ComplexQueries.query(query, object_list);
当然,您需要一些地方来保存您的可搜索数据,因此我可能会与localStorage一起使用。
第3。在localStorage 之上添加indexStorage 您可以在localStorage之上添加索引,如下所示:
mySearchFiles = JIO.newJio({
"type": "indexed",
"indices": [
{"name":"index_name", "fields":["field_to_be_indexed_1"]},
{"name":"index_name2", "fields":["field_to_be_indexed_1","field_to_be_indexed_2"]}
],
"field_types": {
"field_to_be_indexed_1": "string",
"field_to_be_indexed_2": "string"
},
"sub_storage": {
"type": "local",
"username": "whatever",
"application_name": "fulltextsearch"
}
});
这将为您添加到localstorage的所有文档创建索引,这样您就可以在使用complexQueries挖掘所有文件之前对文件执行关键字搜索。所以:
mySearchFiles.put({
"_id": "your_id",
"search_result_string": "page_title/page_filename",
"index_field": "keyword",
"index_field2": "another_keyword",
"searchable_text": "your_text_to_be_searched_goes_here",
function (err, response) {
// console.log(response) =
// {
// "ok": true,
// "id": "your_id",
// }
}
);
您可以调用相同的方法,但JIO将始终首先尝试查询索引以构建结果。实际上这对于远程存储位置更有用(在请求HTTP请求文件之前搜索索引...比如说... S3),但是,也许可以使用。
如果您有任何疑问,请与我联系。
答案 2 :(得分:0)
听起来你的html文件是静态的,如果是这种情况,你实际上也可以在每个html文件中都有一个带有文本的json文件。
例如,让我们坐下你有两个html页面,foo.html和bar.html,然后你可以从每个页面中提取相关内容并创建一个包含以下内容的json文件:
[{
"id": "foo.html",
"text": "whatever text is in foo.html"
},{
"id": "bar.html",
"text": "whatever text is in bar.html"
}]
这将存在于您的html目录中,例如
- project_dir
-- foo.html
-- bar.html
-- index.json
然后您可以将索引文件与lunr.js一起使用。
如何实际构建index.json文件取决于您可用的工具,尽管boilerpipe或可读性等。这里讨论了更多选项http://readwrite.com/2011/03/19/text-extraction