使用Node.js中的查询字符串过滤对象数组

时间:2018-08-17 18:56:18

标签: javascript node.js

我想根据用户在Node.js中提供的查询字符串来过滤对象数组。有rqlorql之类的软件包可以实现此目的,但是它们似乎对包含冒号的字符串(例如时间戳)有问题。使用rql的代码:

var rql = require("rql/js-array");
var query1 = "time=lt=2018-08-06";
var query2 = "time=lt=2018-08-06T13:45:36.000Z"

var products = [
 {price:14.99, rating: 5, time: "2018-08-04T13:45:36.000Z"},
 {price:5.99, rating: 3, time: "2018-08-05T13:45:36.000Z"},
 {price: 16.5, rating:2, time: "2018-08-06T13:45:36.000Z"}];

console.log(rql.query(query1, {}, products)); // works
console.log(rql.query(query2, {}, products)); // gives error

错误消息:

URIError: Unknown converter 2018-08-06T13
at stringToValue (/home/runner/node_modules/rql/parser.js:186:10)
at /home/runner/node_modules/rql/parser.js:99:20
at String.replace (<anonymous>)
at parse (/home/runner/node_modules/rql/parser.js:71:33)
at Object.query (/home/runner/node_modules/rql/js-array.js:358:10)

与orql类似:

var orql = require('orql');

var query1 = "time=lt=2018-08-06";
var query2 = "time=lt=2018-08-06T13:45:36.000Z"

var products = [
  {price:14.99, rating: 5, time: "2018-08-04T13:45:36.000Z"},
  {price:5.99, rating: 3, time: "2018-08-05T13:45:36.000Z"},
  {price: 16.5, rating:2, time: "2018-08-06T13:45:36.000Z"}];

console.log(orql(products, query1)); // works
console.log(orql(products, query2)); // gives error

错误消息:

TypeError: Cannot read property 'name' of null
at rqlNodeToFunc (/home/runner/node_modules/orql/index.js:351:20)
at Function.rql.compile (/home/runner/node_modules/orql/index.js:65:14)
at rql (/home/runner/node_modules/orql/index.js:48:14)

有什么想法要对带有时间戳的对象数组进行查询吗?

3 个答案:

答案 0 :(得分:1)

尝试使用Lodash。

  

npm install lodash --save

按日期过滤:

_.filter(products, function(element) { return element.time.includes('2018-08-04') })

在日期之间过滤:

let startDate = new Date('08/01/2018');
let endDate = new Date('08/06/2018');

_.filter(products, function (element) {
    let date = new Date(element.time);
    return date >= startDate && date <= endDate;
});

in action看到它。

要仅获得一个结果,请使用_.find而不是_.filter

答案 1 :(得分:0)

JavaScript也有过滤方法。参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

var products = [
 {price:14.99, rating: 5, time: "2018-08-04T13:45:36.000Z"},
 {price:5.99, rating: 3, time: "2018-08-05T13:45:36.000Z"},
 {price: 16.5, rating:2, time: "2018-08-06T13:45:36.000Z"}
];

const byRating = function(rating) {
  return products.filter(product => product.rating === rating)
}

const withRatingFive = byRating (5); // 5 can be a parameter from your users.

const priceLowerThan = function(price) {
  return products.filter(product => product.price < price)
}

const cheapestProduct = priceLowerThan(6); // 6 can be a parameter from your users.

const dateBetween = function(start,end) {
  return products.filter(product => (product.time >= start && product.time <= end))
}

仅提供一些示例,可以为您提供正确的指导。

答案 2 :(得分:0)

似乎是rql解析器中的错误,因为the documentation说它支持“不带冒号编码的ISO UTC格式”:

  

查询中的值可以是字符串(使用URL编码),数字,布尔值,空值,未定义和日期(不带冒号编码的ISO UTC格式)。

您可以在日期前添加单词string来解决该问题。

var query2 = "time=lt=string:2018-08-06T13:45:36.000Z"

或也对冒号进行编码(用%3A 代替):

var query2 = "time=lt=2018-08-06T13%3A45%3A36.000Z";