繁体   English   中英

MongoDB/Mongoose 查询生成器

[英]MongoDB/Mongoose Query Builder

我正在尝试构建一个查询构建器,它允许我根据用户输入的参数过滤数据。 我的数据模型是这样的:

{
"_id": {
    "$oid": "871287215784812"
},
"tags": [
    "school",
    "book",
    "bag",
    "headphone",
    "appliance"
],

"consultingDays": 57,
"client": "someOne",
"subSector": "something",
"region": "UK",
"__v": 0
}

目前我的查询生成器如下所示:

app.post('/user/test',function(req, res) {

var query = {};

//QUERY NO.1 - This works perfectly
if (req.body.region){
    query.region = req.body.region
    console.log(query.region)
}

// QUERY NO.2 - This works perfectly  
if (req.body.subSector){
    query.subSector = req.body.subSector
}

Project.find(query, function(err, project){
    if (err){
        res.send(err);
    }
    console.log(project);
    res.json(project);
});
});

我的问题:

我想创建一个查询,该查询将从用户那里获取输入并解析“标签”数组并返回所需的 JSON。

例如:

如果用户请求一个包含“学校”、“书”、“包”的对象,它将返回该对象,如上面我的数据模型所示。 但是如果用户请求一个带有“school”、“book”、“ninja Warrior”的对象,它不会返回任何数据,因为数据库中没有对象包含所有这 3 个字符串。

我尝试过的:

我已经尝试了以下

if (req.body.sol){
    query.solutions = {"tags" : {$in: [req.body.sol]}} 
}

或者

if (req.body.sol){
    query.solutions = {$elemMatch:{tags: req.body.sol}}
}

或者

 if (req.body.sol){
    query.solutions = { tags: { $all: [req.body.sol]}}
}

请求是这样发送的,它们返回一个空数组:

在此处输入图片说明

还有一个问题是用户将获得下拉选项。 例如,他/她可能会得到 3 个下拉框。 每个下拉框将显示标签数组中的所有五个选项。 用户将为每个下拉框选择一个值。 然后过滤结果。 因为数据库中可能有一个对象在标签数组中包含“book”、“bag”、“shoes”。 用户可以在标签数组中选择这五个关键字的任意组合

有谁知道我该如何解决这个问题?

您需要将数组作为sol发送,因此在 Postman 中您应该使用sol[0]sol[1]等更改sol 。然后使用:

if (req.body.sol){
    query.solutions = {"tags" : {$in: req.body.sol}} 
}

没有[]因为req.body.sol是一个数组。

我为嵌套对象实现了一个简单的查询构建:

const checkObject = (object) => {
  let key;

  const status = Object.entries(object).some(([objectKey, objectValue]) => {
    if (typeof objectValue === "object" && objectValue !== null) {
      key = objectKey;

      return true;
    }

    return false;
  });

  return { status, key };
};

const queryBuilder = (input) => {
  // Array verification not implemented
  let output = {};

  _.each(input, (value, key) => {
    if (typeof value === "object" && value !== null) {
      _.each(value, (nestedValue, nestedKey) => {
        output[`${[key, nestedKey].join(".")}`] = nestedValue;
      });
    } else {
      output[key] = value;
    }
  });

  const cacheCheckObject = checkObject(output);

  if (cacheCheckObject.status)
    return { ..._.omit(output, cacheCheckObject.key), ...queryBuilder(output) };

  return output;
};

我还没有实现数组,但是通过一些小工作你可以做到。 Mongo 运营商也是如此。 完整的例子可以在Gist上看到。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM