首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在javascript中优化JSON查询性能

在javascript中优化JSON查询性能
EN

Stack Overflow用户
提问于 2017-11-26 08:42:09
回答 1查看 3.2K关注 0票数 7

我有一个10 of的JSON文件,其结构如下(10k条目):

代码语言:javascript
复制
{
entry_1: {
    description: "...",
    offset: "...",
    value: "...",
    fields: {
        field_1: {
            offset: "...",
            description: "...",
        },
        field_2: {
            offset: "...",
            description: "...",
        }   
    }
},
entry_2:
...
...
...

}

我希望实现一个自动完成输入字段,该字段将在搜索多个属性时尽可能快地从该文件中获取建议。例如,查找包含某些子字符串的所有条目名称、字段名和描述。

方法1:

我试图将嵌套简化为一个字符串数组:

代码语言:javascript
复制
"entry_1|descrption|offset|value|field1|offset|description",
"entry_1|descrption|offset|value|field2|offset|description",
"entry2|..."

并执行不区分大小写的部分字符串匹配,查询占用约900 and。

方法2

我尝试了基于Xpath的JSON查询(使用defiant.js)。

代码语言:javascript
复制
  var snapshot = Defiant.getSnapshot(DATA);
  found = JSON.search(snapshot, '//*[contains(fields, "substring")]');

查询花费了大约600 for (仅针对一个属性fields)。

还有其他的选择可以让我获得100毫秒以下的服务吗?我对文件格式有控制,所以我可以将它转换成XML或任何其他格式,唯一的要求是速度。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-26 17:00:46

由于您正在尝试搜索值的子字符串,所以按照建议使用indexeddb并不是一个好主意。您可以尝试将字段的值扁平化为文本,其中由::分隔的字段和对象中的每个键都是文本文件中的一行:

代码语言:javascript
复制
{
  key1:{
    one:"one",
    two:"two",
    three:"three"
  },
  key2:{
    one:"one 2",
    two:"two 2",
    three:"three 2"
  }
}

将是:

代码语言:javascript
复制
key1::one::two::three
key2::one 2::two 2::three

然后使用regexp搜索keyN::部件之后的文本,并存储所有匹配的键。然后将所有这些键映射到对象。因此,如果key1是唯一匹配的,您将返回data.key1

下面是一个包含10000个键的示例数据(在膝上型计算机上搜索需要几毫秒,但当节流到移动时还没有测试):

代码语言:javascript
复制
//array of words, used as value for data.rowN
const wordArray = ["actions","also","amd","analytics","and","angularjs","another","any","api","apis","application","applications","are","arrays","assertion","asynchronous","authentication","available","babel","beautiful","been","between","both","browser","build","building","but","calls","can","chakra","clean","client","clone","closure","code","coherent","collection","common","compiler","compiles","concept","cordova","could","created","creating","creation","currying","data","dates","definition","design","determined","developed","developers","development","difference","direct","dispatches","distinct","documentations","dynamic","easy","ecmascript","ecosystem","efficient","encapsulates","engine","engineered","engines","errors","eslint","eventually","extend","extension","falcor","fast","feature","featured","fetching","for","format","framework","fully","function","functional","functionality","functions","furthermore","game","glossary","graphics","grunt","hapi","has","having","help","helps","hoisting","host","how","html","http","hybrid","imperative","include","incomplete","individual","interact","interactive","interchange","interface","interpreter","into","its","javascript","jquery","jscs","json","kept","known","language","languages","library","lightweight","like","linked","loads","logic","majority","management","middleware","mobile","modular","module","moment","most","multi","multiple","mvc","native","neutral","new","newer","nightmare","node","not","number","object","objects","only","optimizer","oriented","outside","own","page","paradigm","part","patterns","personalization","plugins","popular","powerful","practical","private","problem","produce","programming","promise","pure","refresh","replace","representing","requests","resolved","resources","retaining","rhino","rich","run","rxjs","services","side","simple","software","specification","specifying","standardized","styles","such","support","supporting","syntax","text","that","the","their","they","toolkit","top","tracking","transformation","type","underlying","universal","until","use","used","user","using","value","vuejs","was","way","web","when","which","while","wide","will","with","within","without","writing","xml","yandex"];
//get random number
const rand = (min,max) =>
  Math.floor(
    (Math.random()*(max-min))+min
  )
;
//return object: {one:"one random word from wordArray",two:"one rand...",three,"one r..."}
const threeMembers = () =>
  ["one","two","three"].reduce(
    (acc,item)=>{
      acc[item] = wordArray[rand(0,wordArray.length)];
      return acc;
    }
    ,{}
  )
;
var i = -1;
data = {};
//create data: {row0:threeMembers(),row1:threeMembers()...row9999:threeMembers()}
while(++i<10000){
  data[`row${i}`] = threeMembers();
}
//convert the data object to string "row0::word::word::word\nrow1::...\nrow9999..."
const dataText = Object.keys(data)
  .map(x=>`${x}::${data[x].one}::${data[x].two}::${data[x].three}`)
  .join("\n")
;
//search for someting (example searching for "script" will match javascript and ecmascript)
//  i in the regexp "igm" means case insensitive
//return array of data[matched key]
window.searchFor = search => {
  const r = new RegExp(`(^[^:]*).*${search}`,"igm")
  ,ret=[];
  var result = r.exec(dataText);
  while(result !== null){
    ret.push(result[1]);
    result = r.exec(dataText);
  }
  return ret.map(x=>data[x]);
};
//example search for "script"
console.log(searchFor("script"));

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47494373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档