2014-11-24 58 views
0

我正在尝试使用JavaScript和JSON编写一个基本的实验性搜索系统,其中包含JSON文件中包含的可搜索数据。文件中列出了多个“帖子”,每个帖子都有一个“标签”数组。我的意图是搜索每个帖子标签,并只检索标签与查询匹配的帖子,比如“有趣的猫咪视频”(帖子必须包含所有三个标签,“有趣”,“猫”和“视频“,待退回)。如何在Javascript中使用JSON进行多维搜索?

我特别关心的是性能。我相信这种技术会效率低下,因为大约有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]); 
     } 
    } 
} 

不幸的是,我无法弄清楚如何让它只返回具有全部三个标签的帖子,并且它返回具有提供的任何标签的所有帖子。不仅如此,它还会返回重复项。

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

+0

我要重申,这必须是JavaScript的。如果使用数据库在服务器端写这些东西,我会更加高兴,但这不是一种选择。 – Forest 2014-11-24 17:33:09

+0

你考虑过使用[IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)吗?它是客户端,但正如名字所暗示的那样,它是为性能而编制的。 – 2014-11-24 17:36:50

+0

这实际上很有趣,约旦,但我需要该页面能够加载任何计算机并执行相同的操作,因此加载文件。除非我错过了一些东西,IndexedDB需要将数据存储在浏览器中? – Forest 2014-11-24 17:39:22

回答

1

你需要使用一个标志,并且只有当它们全部找到时才“写”出匹配,当发现一个标志时,你就会写出它。 Plus 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

+0

谢谢!这就是我一直在寻找的。我不敢相信我没有想到这一点。 – Forest 2014-11-24 18:37:47

+0

我很好奇这将是2000个职位的表现。 – 2014-11-24 18:47:06

+0

我同意乔丹,这也是我为什么要对IndexedDB做更多研究,并找出更快的原因。任何更优化的东西都可能是好的。 – Forest 2014-11-24 19:22:30