2

我正在尝试在客户端计算机上实现基于全文的搜索功能。

我发现Lunr.js部分满足了我的要求,但它必须加载到像 Apache 这样的服务器上,然后才能完美运行。

就我而言,客户端机器不会安装任何服务器或数据库。一个目录中只有一堆静态 HTML 文件,一个索引文件接受来自搜索框的用户输入,该搜索框在这些静态 HTML 文件中搜索此字符串。

谷歌搜索发现了一些有趣的词,这些词(可能)在我的项目中需要:innerHtml、、DOM和。iframesRegExp

请根据您的回答制定我的疑问。提前致谢

4

3 回答 3

2

我可以想到一种方法 - 您可以使用 XMLHttpRequest 获取本地文件。默认情况下不允许这样做,但例如可以使用以下参数启动 chromium:

--allow-file-access-from-files

您必须浏览所有要查看的文件并通过剥离 html 标记并执行正则表达式来手动实现搜索,这应该不难。

我在铬中测试了以下代码:

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();
于 2013-03-30T14:22:09.823 回答
1

虽然我没有尝试以这种方式使用它,但你可以看看jIO ( Github )

jIO 可用于跨多个存储(浏览器 localstorage、webDav、xWiki、S3...)管理和同步 JSON 文档。存储可以被索引,并且 jIO 带有它自己的查询模块,称为 complexQueries,也可以独立使用。

如果您通过 Ajax 请求页面并提取页面的全文/HTML,只需将其作为文档转储到 jIO 中。

三种方法(jIO 文档中的所有示例):

1) 使用普通的本地存储和复杂的查询
在 jIO 中为您想要搜索的每个文档创建一个文档。所以在设置你的 jIO 之后:

var mySearchFiles = JIO.newJio({
    "type" : "local",
    "username" : "whatever",
    "application_name" : "fulltextsearch"
 });

将完整的 HTML/提取文本(本地存储大小限制...)添加为文档,如下所示:

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 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中使用的parseserialize和方法。query查看上面的示例页面链接,了解它是如何工作的。

基本上,您需要将要搜索的数据作为对象列表提供,并且您的查询必须被序列化。然后只需调用:

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"
    }
});

这将为您添加到本地存储的所有文档创建一个索引,这将允许您在使用 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),但尽管如此,也许还是有用的。

如果您有任何问题,请告诉我。

于 2013-03-30T16:10:19.063 回答
0

听起来您的 html 文件是静态的,如果是这种情况,您实际上还可以拥有一个 json 文件,其中包含每个 html 文件中的文本。

例如,假设您有两个 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 文件取决于您可以使用哪些工具,尽管类似于锅炉管道或可读性。这里讨论了更多选项http://readwrite.com/2011/03/19/text-extraction

于 2013-06-27T09:28:02.290 回答