搜索大型多嵌套JSON数据集的最有效方法是什么?

时间:2016-01-23 12:21:40

标签: javascript jquery json

使用jQuery或JS搜索大型JSON数据集(最多27k条目)的最有效方法是什么。我想创建一个在keyup上运行函数的搜索字段。

因此,如果用户开始输入,则会返回与标题匹配的所有值以及该标题的链接。

我的JSON按字母顺序嵌套A-Z。以下示例

"Numbers": [
  {
   "Title": "20th Century Period Pieces",
   "Link": "#"
  },
  {
   "Title": "20th Century",
   "Link": "#"
  }
 ],
 "A": [
  {
   "Title": "Action Comedies",
   "Link": "#"
  },
  {
   "Title": "Action",
   "Link": "#"
  }
],
 "B": [
  {
   "Title": "British",
   "Link": "#"
  },
  {
   "Title": "Borderline",
   "Link": "#"
  }
],
// And so forth

我知道这可能导致浏览器冻结在每个键盘上搜索如此大的列表,因此我可能不得不恢复搜索按钮并加载动画。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:0)

你可以实现一个树形结构,它可以让你更有效地搜索,所以我不认为这是你想要做的。您也可以让后端处理搜索并给出结果,这就是我要做的。所以让PHP处理搜索查询并返回一个新的JSON集。你的最后一个选择就是让浏览器冻结。

我更喜欢PHP解决方案。加载动画可以等到PHP返回数据然后显示它。这使用服务器处理请求,所以没有任何东西会冻结 - 在我看来这是一个非常好的解决方案。

对于用户,我建议如下:注册击键并给它一个“超时”。一旦用户没有输入500ms,请查询PHP脚本。您可以通过XMLHttpRequest执行此操作,并使用JSON.parse解析结果。这里根本不需要jQuery。

答案 1 :(得分:0)

就我个人而言,如果您为数据创建API并通过AJAX请求对其进行过滤,我认为您应该将所有数据发送到客户端,这将返回过滤结果。查看您的示例数据,似乎这不是用户特定的,因此从数据库/任何地方提取数据并缓存它似乎是最佳解决方案。

jQueryUI自动完成有一个关于如何实现此here

的示例

这是他们的示例,每当用户输入至少3个字符时发出AJAX请求:

$( "#city" ).autocomplete({
      source: function( request, response ) {
        $.ajax({
          url: "http://gd.geobytes.com/AutoCompleteCity",
          dataType: "jsonp",
          data: {
            q: request.term
          },
          success: function( data ) {
            response( data );
          }
        });
      },
      minLength: 3,
      select: function( event, ui ) {
        log( ui.item ?
          "Selected: " + ui.item.label :
          "Nothing selected, input was " + this.value);
      },
      open: function() {
        $( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
      },
      close: function() {
        $( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
      }
    });

您不必使用jQuery Autocomplete,但您明白了。

答案 2 :(得分:0)

使用更易于搜索的结构创建地图

var map = [];

(function _search(o) {
    if ( typeof o !== 'object' ) return;
    if (Array.isArray(o)) {
        o.forEach(function(item) { _search(item) });
    } else if ('Title' in o) {
        map.push(o);
    } else {
        for (var key in o) {
            if ( typeof o[key] === 'object' ) {
                if ( Array.isArray(o[key]) ) {
                    o[key].forEach(function(item) { _search(item) });
                } else {
                    _search(o[key]);
                }
            }
        }
    }
}(obj));

然后你可以过滤地图

var result = map.filter(function(obj) {
    return obj.Title.toLowerCase().indexOf(SearchValue.toLowerCase()) === 0;
});

FIDDLE