【问题标题】:How to search each document field individually for specific value?如何单独搜索每个文档字段以获取特定值?
【发布时间】:2014-11-14 06:40:49
【问题描述】:

我有一个搜索栏,当用户按下回车键时,搜索栏中的字符串会发送到我的 ExpressJS 服务器。然后,服务器需要查看 MongoDB 中的每个文档;如果文档的任何字段与搜索栏中的内容匹配,则会找到文档。

我当前的代码在技术上是可行的,但它似乎非常多余并且可能非常低效。我在每个字段上使用 find() 方法,将匹配项保存在数组中。在单独搜索每个字段后,我会修剪找到的匹配数组,删除所有重复项。

有没有更好的方法来做到这一点?请参阅下面的当前代码:

router.get('/', function(req, res) {
    var regSearch = new RegExp('.*'+searchdata+'.*', 'i'); //Create regular expression of search data -> (text in search bar)
    var arr = [];


    InventoryObject.find({productId: {$regex: regSearch}}).limit(100).exec(function (err, data) {    //Get all docs with a matching productId
      InventoryObject.find({scannerIn: {$regex: regSearch}}).limit(100).exec(function (err, data1) {    //Get all docs with a matching scannerIn
        InventoryObject.find({scannerOut: {$regex: regSearch}}).limit(100).exec(function (err, data2) {    //Get all docs with a matching scannerOut....
          InventoryObject.find({dateIn: {$regex: regSearch}}).limit(100).exec(function (err, data3) {
            InventoryObject.find({dateOut: {$regex: regSearch}}).limit(100).exec(function (err, data4) {
              InventoryObject.find({productName: {$regex: regSearch}}).limit(100).exec(function (err, data5) {
                InventoryObject.find({purchaseOrder: {$regex: regSearch}}).limit(100).exec(function (err, data6) {
                  InventoryObject.find({productDestination: {$regex: regSearch}}).limit(100).exec(function (err, data7) {

                    InventoryObject.find({productCost: parseFloat(searchdata)}).limit(100).exec(function (err, data8) {

                      //Concatenate all matched documents into single array
                      arr = arr.concat(data, data1, data2, data3, data4, data5, data6, data7, data8);

                      //Remove undefined last element...
                      arr.splice(arr.length-1, 1);

                      //Iterate through array and remove any documents that are duplicates 
                      for (var i = 0; i < arr.length; i++) {
                        for (var j = i+1; j < arr.length; j++) {
                          if (arr[i]._id.toString() === arr[j]._id.toString()) {
                            arr.splice(j, 1);
                            j--;
                          }
                        }
                      }

                      //Sort the documents by their _id property
                      arr.sort(function (a, b) {
                        if (a._id < b._id) return +1;
                        if (a._id > b._id) return -1;
                        return 0;
                      });

                      //If the array is longer than 100, truncate it.
                      if (arr.length > 100)
                        arr.length = 100;    //truncate to 100 elements sorted by the order they were inputted

                      //console.log(arr);

                      res.render('index', {'inventoryObjects': arr});
                      searchdata = ''; //Clear search data    
                    });    
                  });    
                });    
              });    
            });    
          });    
        });    
      });
    });
  });

这是我的架构供参考:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var InventoryObject = new Schema({
    productId: String,
    scannerIn: String,
    scannerOut: String,
    dateIn: String,
    dateOut: String,
    productName: String,
    purchaseOrder: String,
    productDestination: String,
    productCost: Number
});
mongoose.model('InventoryObject', InventoryObject);

【问题讨论】:

  • 您是否考虑过创建一个包含您要搜索的所有列的text index,然后使用$text 查询?

标签: regex node.js mongodb express mongoose


【解决方案1】:

很遗憾,这在当前的 Mongo DB 版本中是不可能的。

您应该像这样优化您的查询:

InventoryObject.find({
    $or:[
        {productId: {$regex: regSearch}}, 
        {scannerIn: {$regex: regSearch}}, 
        ...
    ]
});

但如果您确实需要优化此类查询的速度,您应该将架构更改为:

{
    attributes: [
        {key: 'productId', value: 'product ID'},
        {key: 'scannerId', value: 'scanner ID'},
        ...
    ]
}

【讨论】:

  • 非常感谢!一个明确的回应。我使用了您建议的第一个优化,因为我有点时间紧迫。它比我的原始代码更好,而且更简洁!谢谢!
猜你喜欢
  • 2021-07-25
  • 1970-01-01
  • 2022-11-14
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
  • 1970-01-01
  • 1970-01-01
  • 2020-08-26
相关资源
最近更新 更多