最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - MongoDBMongoose Query Builder - Stack Overflow

programmeradmin2浏览0评论

I am trying to build a query builder which will allow me to filter the data based on the parameters entered by user. My Data Model is like so:

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

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

Currently my Query Builder looks like this:

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);
});
});

My Question:

I want to create a query which will take input from user and parse the "tags" array and return the required JSON.

For example:

If the user requests an object which contains "school", "book", "bag" it will return the object as seen my data model above. But if the user requests an object with "school", "book", "ninja Warrior" it won't return any data as no object within the database contain all those 3 strings.

What I have tried:

I have tried the following

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

OR

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

OR

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

The requests were sent like so and they returned an empty array:

Also the issue is that the user will get dropdown options. For example he/she might get 3 dropdown boxes. Each dropdown box will display all the five options in the tags array. The user will select a value for each dropdown box. And then filter the result. Because there might be an object within the database that contains "book", "bag", "shoes" within the tags array. The user can select any bination of those five keywords in the tags array

Does anyone know how I can fix this?

I am trying to build a query builder which will allow me to filter the data based on the parameters entered by user. My Data Model is like so:

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

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

Currently my Query Builder looks like this:

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);
});
});

My Question:

I want to create a query which will take input from user and parse the "tags" array and return the required JSON.

For example:

If the user requests an object which contains "school", "book", "bag" it will return the object as seen my data model above. But if the user requests an object with "school", "book", "ninja Warrior" it won't return any data as no object within the database contain all those 3 strings.

What I have tried:

I have tried the following

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

OR

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

OR

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

The requests were sent like so and they returned an empty array:

Also the issue is that the user will get dropdown options. For example he/she might get 3 dropdown boxes. Each dropdown box will display all the five options in the tags array. The user will select a value for each dropdown box. And then filter the result. Because there might be an object within the database that contains "book", "bag", "shoes" within the tags array. The user can select any bination of those five keywords in the tags array

Does anyone know how I can fix this?

Share Improve this question edited Dec 14, 2015 at 12:09 Skywalker asked Dec 14, 2015 at 11:30 SkywalkerSkywalker 5,20417 gold badges66 silver badges127 bronze badges 1
  • Your $all query is close, but try query = { tags: { $all: req.body.sol}}. – JohnnyHK Commented Dec 14, 2015 at 13:50
Add a ment  | 

2 Answers 2

Reset to default 2

You need to send an array as sol so in Postman you should change sol with sol[0], sol[1], etc.. Then use this:

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

Without the [] because req.body.sol is an array yet.

I have implemented a simple query build for nested objects:

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;
};

I have not implemented array, but with some small work you can do it work. The same for Mongo operators. The plete example can be seen on Gist.

发布评论

评论列表(0)

  1. 暂无评论