【问题标题】:How can I do a multidimensional search with JSON in Javascript?如何在 Javascript 中使用 JSON 进行多维搜索?
【发布时间】:2015-01-22 12:16:13
【问题描述】:

我正在尝试使用 JavaScript 和 JSON 编写一个基本的实验性搜索系统,可搜索的数据包含在 JSON 文件中。文件中列出了多个“帖子”,每个帖子都有一个“标签”数组。我的意图是搜索每个帖子标签,并仅检索具有与查询匹配的标签的帖子,例如“funny cat video”(帖子必须具有所有三个标签,“funny”、“cat”和“视频”,待退回)。

我特别关心的是性能。我确信这种技术效率很低,因为大约有 2000 个帖子,每个帖子都有 5 到 50 个标签,但必须使用 JavaScript 完成。我已经从这个网站上参考了如何最大限度地提高性能,尽管我可以通过一些额外的帮助来做。

这是我目前用于存储数据的代码:

{
    "index": {
        "count": "2",
        "posts": [
            {
                "id": "1",
                "date": "2014-11-21 17:16:39 GMT",
                "url": "http://url/",
                "image": "http://big_image/",
                "thumbnail": "http://little_image/",
                "tags": ["funny", "cat", "picture", "falling", "chair", "window sill", "funny"]
            },
            {
                "id": "2",
                "date": "2014-11-20 17:57:32 GMT",
                "url": "http://url1/",
                "image": "http://big_image1/",
                "thumbnail": "http://little_image1/",
                "tags": ["funny", "cat", "picture", "jumping", "water", "bath", "funny"]
            }
        ]
    }
}

这是我的 Javascript:

var query = "funny cat bath".split(" ");
var data = JSON.parse("THE JSON GOES HERE");
var count = data.index.count;
var index = data.index.posts;
for (var i = 0, indexLength = index.length; i < indexLength; i++) {
    tags = index[i].tags;
    for (var q = 0, queryLength = query.length; q < queryLength; q++) {
        if(tags.indexOf(query[q]) !== false) {
            console.log(index[i]);
        }
    }
}

不幸的是,我不知道如何让它只返回具有所有三个标签的帖子,并返回所有带有任何标签的帖子。不仅如此,它还会返回重复项。

有人有更好的解决方案吗?我被卡住了。

【问题讨论】:

  • 我想重申,这必须是 JavaScript。我会更乐意在服务器端使用数据库编写此内容,但这不是一个选择。
  • 您是否考虑过改用IndexedDB?它是客户端,但顾名思义,它是为性能而编制索引的。
  • 这实际上很有趣,Jordan,但我需要该页面能够在任何计算机上加载并执行相同的操作,从而加载文件。除非我遗漏了什么,否则 IndexedDB 需要将数据存储在浏览器中?
  • 无论哪种方式,您都必须将数据存储在浏览器中。在一种情况下,您将数据放入一个普通的旧 JavaScript 对象中;在另一种情况下,您将数据放入 IndexedDB 数据库。
  • 我将了解更多相关信息,但我现在将使用公认的答案,直到我弄清楚如何使用 IndexedDB!

标签: javascript arrays json performance search


【解决方案1】:

您需要使用一个标志,并且仅在找到所有匹配项时“写出”匹配项,当找到一个匹配项时才将其写出。加上 indexOf 返回 -1,而不是 false。基本思路如下:

var data = {
    "index": {
        "count": "2",
        "posts": [
            {
                "id": "1",
                "date": "2014-11-21 17:16:39 GMT",
                "url": "http://url/",
                "image": "http://big_image/",
                "thumbnail": "http://little_image/",
                "tags": ["funny", "cat", "picture", "falling", "chair", "window sill", "funny"]
            },
            {
                "id": "2",
                "date": "2014-11-20 17:57:32 GMT",
                "url": "http://url1/",
                "image": "http://big_image1/",
                "thumbnail": "http://little_image1/",
                "tags": ["funny", "cat", "picture", "jumping", "water", "bath", "funny"]
            }
        ]
    }
};


var query = "funny cat bath".split(" ");
var filteredSet = [];  //where the matched objects will reside
var posts = data.index.posts;  //get the posts
for (var i=0; i<posts.length;i++) {  //loop through the posts
    var post = posts[i];  
    var tags = post.tags;  //reference the tags
    var hasMatch = true;  //flag to hold the state if we have a good match - set to true by default
    for (var j=0; j<query.length; j++) {  //loop through the tags the user is looking for
        var index = tags.indexOf(query[j]);  //look for it in the set [Note older IEs needs polyfill see MDN for code]
        if (index===-1) { //indexOf returns -1 if not found
            hasMatch=false;  //set Boolean flag so we do not record item
            break;  //exit loop - no reason to keep checking
        }
    }
    if (hasMatch) { //if we found all the tags
        filteredSet.push(post); // add to the filtered set
    }
}
console.log(filteredSet);  //show the filtered set

【讨论】:

  • 谢谢!这就是我一直在寻找的。我不敢相信我没有想到这一点。
  • 我同意,Jordan,这就是为什么我还要对 IndexedDB 进行更多研究,并找出更快的方法。任何更优化的东西都可能会很好。
猜你喜欢
  • 2011-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-24
  • 1970-01-01
  • 2014-11-29
  • 1970-01-01
  • 2014-05-06
相关资源
最近更新 更多