使用带有精确标签的Javascript搜索JSON [英] Searching a JSON with Javascript with exact tags

查看:76
本文介绍了使用带有精确标签的Javascript搜索JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下JSON,其中将通过选择过滤器来执行搜索:

{
  "Books": [
     {
        "title": "Book 1",
        "binding": "paperback",
        "category": "pop",
        "language": "english",
        "author": "male"
     },
     {
        "title": "Book 2",
        "binding": "hardcover",
        "category": "pop rock,electro pop",
        "language": "french",
        "author": "female"
     },
     {
        "title": "Book 3",
        "binding": "audiobook",
        "category": "soft rock",
        "language": "german",
        "author": "male,female"
     },
     {
        "title": "Book 4",
        "binding": "boxed set",
        "category": "rock,classic rock",
        "language": "english",
        "author": "female,male"
     },
     {
        "title": "Book 5",
        "binding": "paperback",
        "category": "electro pop,rock,classic rock",
        "language": "french",
        "author": "male/female"
     },
     {
        "title": "Book 6",
        "binding": "paperback",
        "category": "rock",
        "language": "french",
        "author": "male"
     }
  ]
}

可用的过滤器

Binding
  -Paperback
  -Hardcover
  -Audiobook
  -Boxed Set

Category
  -Classic Rock
  -Pop
  -Pop Rock
  -Electro Pop
  -Soft Rock
  -Rock

Language
  -German
  -English
  -French

Author
  -Male
  -Female
  -Male/Female

我正在使用 defiant.js 从JSON中搜索.当我使用以下查询时:

var thequery = [];
for (var i in searchTags) {
    for (var j = 0; j < searchTags[i].length; j++) {
        thequery.push('contains(' + i + ' ,"' + searchTags[i][j] + '")');   
    }
}
var thequeryString = thequery.join(' and ');
console.log('//*[' + firstqueryString + ']');
return '//*[' + thequeryString + ']';

因此,当我第一次单击绑定筛选器时,我得到的查询是//*[contains(binding ,"paperback")],而当我第二次单击时,返回的查询是//*[contains(binding ,"paperback") and contains(binding ,"boxed set")],这将正确地过滤结果.

但是现在的问题是,如果我想获取具有流派pop的图书,则可以通过查询//*[contains(category ,"rock")]获得

  1. 书2
  2. 书3
  3. 书4
  4. 书5
  5. 书6

但实际上,只有 Book 4 Book 5 Book 6 具有 Rock 类别.

我尝试过的另一个查询是:

var thequery = [];
for (var i in searchTags) {
    for (var j = 0; j < searchTags[i].length; j++) {
        if(i == 'author' || i == 'category'){ 
            thequery.push(i + '[contains(.,"' + searchTags[i][j] + ',")] or ' + i + '[contains(.,",' + searchTags[i][j] + '")] or ' + i + '="' + searchTags[i][j] + '"');
        }else{
            thequery.push('contains(' + i + ' ,"' + searchTags[i][j] + '")'); 
        }
    }
}
var thequeryString = thequery.join(' and ');
console.log('//*[' + firstqueryString + ']');
return '//*[' + thequeryString + ']';

我得到的查询是//*[category[contains(.,"rock,")] or category[contains(.,", rock")] or category ="rock"],它返回:

  1. 书2
  2. 书4
  3. 书5
  4. 书6

我能得到的最近的只有这里.

所以,总结一下,我有2个问题:

  1. 如何使用我单击的确切过滤器过滤图书.例如.如果我单击摇滚",则仅应返回包含类别摇滚的图书".
  2. 如果我使用//*[category[contains(.,"rock,")] or category[contains(.,", rock")] or category ="rock"]并将其与带有and的主 thequeryString 结合使用,它不会筛选出正确的结果,因为第一个包含./li>

请帮助.

注意: defiantjs 还有一个"XPath Evaluator",您可以在其中检查查询.

解决方案

使用forEach迭代数组,并使用indexOf查找该键中是否存在所需的值

 var m = {
  "Books": [{
      "title": "Book 1",
      "binding": "paperback",
      "category": "pop",
      "language": "english",
      "author": "male"
    },
    {
      "title": "Book 2",
      "binding": "hardcover",
      "category": "pop rock,electro pop",
      "language": "french",
      "author": "female"
    },
    {
      "title": "Book 3",
      "binding": "audiobook",
      "category": "soft rock",
      "language": "german",
      "author": "male,female"
    },
    {
      "title": "Book 4",
      "binding": "boxed set",
      "category": "rock,classic rock",
      "language": "english",
      "author": "female,male"
    },
    {
      "title": "Book 5",
      "binding": "paperback",
      "category": "electro pop,rock,classic rock",
      "language": "french",
      "author": "male/female"
    },
    {
      "title": "Book 6",
      "binding": "paperback",
      "category": "rock",
      "language": "french",
      "author": "male"
    }
  ]
}




// a function which accepts key which is one of binding,category,language,author.
// the array will be filtered on this key
function getFilteredElement(key, value) {
    var bookFilter = [];
    m.Books.forEach(function(item){
       var getFilterField = item[key];
       // since the value is a string, so splitting it and creating an array
       var keyArray = item[key].split(',');
       // now checking if the passed value has a presence in the  above array
       if (keyArray.indexOf(value) !== -1) {
           // if present pushed the book name
           bookFilter.push(item.title);
       }
   });
    // returning the array of books
    return bookFilter;
}

console.log(getFilteredElement('category', 'rock')) 

I have a following JSON where search is to be performed by selecting filters:

{
  "Books": [
     {
        "title": "Book 1",
        "binding": "paperback",
        "category": "pop",
        "language": "english",
        "author": "male"
     },
     {
        "title": "Book 2",
        "binding": "hardcover",
        "category": "pop rock,electro pop",
        "language": "french",
        "author": "female"
     },
     {
        "title": "Book 3",
        "binding": "audiobook",
        "category": "soft rock",
        "language": "german",
        "author": "male,female"
     },
     {
        "title": "Book 4",
        "binding": "boxed set",
        "category": "rock,classic rock",
        "language": "english",
        "author": "female,male"
     },
     {
        "title": "Book 5",
        "binding": "paperback",
        "category": "electro pop,rock,classic rock",
        "language": "french",
        "author": "male/female"
     },
     {
        "title": "Book 6",
        "binding": "paperback",
        "category": "rock",
        "language": "french",
        "author": "male"
     }
  ]
}

Available Filters are

Binding
  -Paperback
  -Hardcover
  -Audiobook
  -Boxed Set

Category
  -Classic Rock
  -Pop
  -Pop Rock
  -Electro Pop
  -Soft Rock
  -Rock

Language
  -German
  -English
  -French

Author
  -Male
  -Female
  -Male/Female

I am using defiant.js to search from JSON. When I use the following query:

var thequery = [];
for (var i in searchTags) {
    for (var j = 0; j < searchTags[i].length; j++) {
        thequery.push('contains(' + i + ' ,"' + searchTags[i][j] + '")');   
    }
}
var thequeryString = thequery.join(' and ');
console.log('//*[' + firstqueryString + ']');
return '//*[' + thequeryString + ']';

So when I first click at binding filter then the query I get is //*[contains(binding ,"paperback")] and when I click for second time the returned query is //*[contains(binding ,"paperback") and contains(binding ,"boxed set")] and this then filters results correctly.

But the problem now is if I want to get the Books which has genre pop then with the query //*[contains(category ,"rock")] I get

  1. Book 2
  2. Book 3
  3. Book 4
  4. Book 5
  5. Book 6

But in actual only Book 4, Book 5 and Book 6 has Rock category.

The other query I tried is:

var thequery = [];
for (var i in searchTags) {
    for (var j = 0; j < searchTags[i].length; j++) {
        if(i == 'author' || i == 'category'){ 
            thequery.push(i + '[contains(.,"' + searchTags[i][j] + ',")] or ' + i + '[contains(.,",' + searchTags[i][j] + '")] or ' + i + '="' + searchTags[i][j] + '"');
        }else{
            thequery.push('contains(' + i + ' ,"' + searchTags[i][j] + '")'); 
        }
    }
}
var thequeryString = thequery.join(' and ');
console.log('//*[' + firstqueryString + ']');
return '//*[' + thequeryString + ']';

And the query I get is //*[category[contains(.,"rock,")] or category[contains(.,", rock")] or category ="rock"] which returns:

  1. Book 2
  2. Book 4
  3. Book 5
  4. Book 6

The nearest I could get is only here.

So, summarising all I have 2 issues:

  1. How to filter Books with the exact filter that I have clicked. E.g. If I click Rock then only Books which contains category rock should be returned.
  2. If I use //*[category[contains(.,"rock,")] or category[contains(.,", rock")] or category ="rock"] and join it with the main thequeryString with and it doesn't filter out the correct result as the first contains or.

Please help.

Note: defiantjs also has an " XPath Evaluator" where you could check the queries.

解决方案

Use forEach to iterate the array and use indexOf to find if the required value is present in that key

var m = {
  "Books": [{
      "title": "Book 1",
      "binding": "paperback",
      "category": "pop",
      "language": "english",
      "author": "male"
    },
    {
      "title": "Book 2",
      "binding": "hardcover",
      "category": "pop rock,electro pop",
      "language": "french",
      "author": "female"
    },
    {
      "title": "Book 3",
      "binding": "audiobook",
      "category": "soft rock",
      "language": "german",
      "author": "male,female"
    },
    {
      "title": "Book 4",
      "binding": "boxed set",
      "category": "rock,classic rock",
      "language": "english",
      "author": "female,male"
    },
    {
      "title": "Book 5",
      "binding": "paperback",
      "category": "electro pop,rock,classic rock",
      "language": "french",
      "author": "male/female"
    },
    {
      "title": "Book 6",
      "binding": "paperback",
      "category": "rock",
      "language": "french",
      "author": "male"
    }
  ]
}




// a function which accepts key which is one of binding,category,language,author.
// the array will be filtered on this key
function getFilteredElement(key, value) {
    var bookFilter = [];
    m.Books.forEach(function(item){
       var getFilterField = item[key];
       // since the value is a string, so splitting it and creating an array
       var keyArray = item[key].split(',');
       // now checking if the passed value has a presence in the  above array
       if (keyArray.indexOf(value) !== -1) {
           // if present pushed the book name
           bookFilter.push(item.title);
       }
   });
    // returning the array of books
    return bookFilter;
}

console.log(getFilteredElement('category', 'rock'))

这篇关于使用带有精确标签的Javascript搜索JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆