将 JSON 查询字符串解析为 JSON 对象
Parsing a JSON query string into a JSON object
API 上的查询结构如下:
../myapi/products?_q=genre,retail_price&_a=g,p&p.gt=10&p.lt=20&g.eq=POP
有两个数组:_q 列出了查询参数,_a 列出了相应的别名。所以 p -> retail_price 和 g -> 流派
我可以将其解析为:
{$and : [ genre: { '$eq': 'POP' }, retail_price: { '$gt': '10' }, retail_price: { '$lt': '20' } ]}
差不多开心了。但是这种方法有几个问题:
1. '$eq' 等而不是 $eq 等
2. 数值现在是字符串 '10'
我认为 (2) 令人讨厌。由于服务器不知道类型(也许它应该是“10”而不是 10)。
所以,我想尝试另一种方法。那就是将它全部解析成一个 queryString 然后用 JSON.parse()
转换它
首先我提出了一些查询字符串并在 shell:
中尝试
db.products.find({$and: [{genre: { $eq: 'ROC'}}, {retail_price: {$gt:7}}, {retail_price: {$lt:10}}]})
很有魅力。
然后我试了这个:
var queryStr = "{$and: [{genre: { $eq: 'ROC'}}, {retail_price: {$gt:7}}, {retail_price: {$lt:10}}]}";
和:(产品是猫鼬模型)
Product.find(JSON.parse(queryStr), function(err, product) {
if (err)
res.send(err);
res.json(product);
});
令我惊讶的是它根本不起作用。
也在做
console.log(JSON.stringify(JSON.parse(queryStr)));
不将输出写入控制台。
这里发生了什么?
首先是queryStr
无效JSON。您拥有的是一个看起来像对象的字符串。但你可能会问 "isn't that JSON?"。简短的回答:没有。长答案:因为 JSON 是一种轻量级数据交换格式,它必须可以被多种语言读取(不仅仅是 Javascript)。因此,引用键是实现这一点的必要条件:
var json = '{"foo": true, "bar": 123}';
var str = '{foo: true, bar: 123}';
console.log(JSON.parse(json)); // Object {foo: true, bar: 123}
console.log(JSON.parse(str)); // SyntaxError: Unexpected token f
因此,您可以 stringify 将查询对象 JSON 然后在将其传递给您的 mongoose 方法之前对其进行解析:
// On the client
var queryJSON = JSON.stringify({$and: [{genre: { $eq: 'ROC'}}, {retail_price: {$gt:7}}, {retail_price: {$lt:10}}]});
// On the server
var query = JSON.parse(queryJSON); // Object
也就是说,回到你原来的两个问题:
- 引用的关键名称:它们在这方面的影响为零,因此根本不必担心。
- 不正确的值类型:您似乎已经有了将查询格式化为正确对象的过程,因此您可以使用
Number
将字符串强制转换为数字值。 (例如 Number('10') // 10
)
API 上的查询结构如下:
../myapi/products?_q=genre,retail_price&_a=g,p&p.gt=10&p.lt=20&g.eq=POP
有两个数组:_q 列出了查询参数,_a 列出了相应的别名。所以 p -> retail_price 和 g -> 流派
我可以将其解析为:
{$and : [ genre: { '$eq': 'POP' }, retail_price: { '$gt': '10' }, retail_price: { '$lt': '20' } ]}
差不多开心了。但是这种方法有几个问题: 1. '$eq' 等而不是 $eq 等 2. 数值现在是字符串 '10'
我认为 (2) 令人讨厌。由于服务器不知道类型(也许它应该是“10”而不是 10)。
所以,我想尝试另一种方法。那就是将它全部解析成一个 queryString 然后用 JSON.parse()
转换它首先我提出了一些查询字符串并在 shell:
中尝试db.products.find({$and: [{genre: { $eq: 'ROC'}}, {retail_price: {$gt:7}}, {retail_price: {$lt:10}}]})
很有魅力。
然后我试了这个:
var queryStr = "{$and: [{genre: { $eq: 'ROC'}}, {retail_price: {$gt:7}}, {retail_price: {$lt:10}}]}";
和:(产品是猫鼬模型)
Product.find(JSON.parse(queryStr), function(err, product) {
if (err)
res.send(err);
res.json(product);
});
令我惊讶的是它根本不起作用。
也在做
console.log(JSON.stringify(JSON.parse(queryStr)));
不将输出写入控制台。
这里发生了什么?
首先是queryStr
无效JSON。您拥有的是一个看起来像对象的字符串。但你可能会问 "isn't that JSON?"。简短的回答:没有。长答案:因为 JSON 是一种轻量级数据交换格式,它必须可以被多种语言读取(不仅仅是 Javascript)。因此,引用键是实现这一点的必要条件:
var json = '{"foo": true, "bar": 123}';
var str = '{foo: true, bar: 123}';
console.log(JSON.parse(json)); // Object {foo: true, bar: 123}
console.log(JSON.parse(str)); // SyntaxError: Unexpected token f
因此,您可以 stringify 将查询对象 JSON 然后在将其传递给您的 mongoose 方法之前对其进行解析:
// On the client
var queryJSON = JSON.stringify({$and: [{genre: { $eq: 'ROC'}}, {retail_price: {$gt:7}}, {retail_price: {$lt:10}}]});
// On the server
var query = JSON.parse(queryJSON); // Object
也就是说,回到你原来的两个问题:
- 引用的关键名称:它们在这方面的影响为零,因此根本不必担心。
- 不正确的值类型:您似乎已经有了将查询格式化为正确对象的过程,因此您可以使用
Number
将字符串强制转换为数字值。 (例如Number('10') // 10
)