【问题标题】:How do I search one array for items from another array in MongoDB?如何在一个数组中搜索 MongoDB 中另一个数组中的项目?
【发布时间】:2017-03-12 08:39:45
【问题描述】:

我有一个具有以下数据结构的users 表:

[{
    userID: 0,
    username: 'test0',
    petsForSale: [
        { type: 'fish' },
        { type: 'cats' }
    ],
    seekingPets: [
        { type: 'dogs' },
        { type: 'birds' }
    ]
},
{
    userID: 1,
    username: 'test1',
    petsForSale: [
        { type: 'guinea pigs' },
        { type: 'dogs' },
        { type: 'hamsters' }
    ],
    seekingPets: [
        { type: 'ferrets' }
    ]
}]

我正在尝试执行一个GET,它根据petsForSaleseekingPets 返回匹配的用户。例如,如果用户正在销售dogs,则他们将显示在seekingPets 中任何具有dogs 的用户的匹配结果列表中。我很接近,这是我到目前为止的路由器代码:

router.get('/:id/findmatches', function(req, res) {
  var db = req.db;
  var collection = db.get('users');
  var uid = req.params.id;

  //var seeking_pets = collection.find({ userID: uid }, { seekingPets: 1 });
  //var seeking_pets = collection.find({ userID: uid }, { seekingPets: { type: 1 }});
  var seeking_pets = [ 'dogs', 'birds' ]; // *Hard-coded is the only way I can get it to work

  collection.find({ petsForSale: { $elemMatch: { type: { $in: seeking_pets }}}}, function(e, docs) {
      res.json(docs);
  });
});

此代码可以编译并与硬编码的seeking_pets 一起正常工作 - 访问/users/0/findmatches 按预期返回用户test1。我被困在从请求中的userID 中提取seekingPets 的列表并在collection.find 中搜索它。这两条注释线是我尝试过的但没有成功。我还尝试将collection 转换为array

【问题讨论】:

  • 为什么不使用 $and 运算符同时查询这两个条件?

标签: javascript arrays node.js mongodb express


【解决方案1】:

由于find 是一个异步方法,您必须实现回调才能获取从数据库返回的值。另请注意,您的硬编码值是字符串,但 seekPets 数组是对象。

试试这个:

router.get('/:id/findmatches', function(req, res) {
  var db = req.db;
  var collection = db.get('users');
  var uid = req.params.id;

  collection.findOne({ userID: uid }, function(err, user)
      var seeking_pets = [].
      for (var i = 0; i < user.seekingPets.length; i++) {
        seeking_pets.push(user.seekingPets[i].type);
      }

      collection.find({ petsForSale: { $elemMatch: { type: { $in: seeking_pets }}}}, function(e, docs) {
          res.json(docs);
      });

  });
});

请注意,我使用findOne 来获取对象而不是数组,并从该对象获取 seekPets 数组。当然你可以改进这段代码,去掉一些可有可无的变量,比如seeking_pets,如果找不到id就处理数据库错误。

【讨论】:

  • 刚刚试过这个没有成功。在findOne 内硬编码seeking_pets 像以前一样工作。还有其他想法吗?
  • 我刚刚注意到你的 userId 是一个数字,你确定 req.params.id 不是一个字符串吗?
  • 同时检查 findOne err 是否不是 undefined 或 null
  • 所以 findOne errnull 并且我检查了 userID 的类型并没有发现任何问题(甚至是硬编码的用户 ID 以确保)。结果和以前一样。我做了一个console.log(user.seekingPets[0].name) 作为测试并返回了正确的名称。我觉得我们越来越近了。
  • 魔术。非常感谢!
猜你喜欢
  • 2014-09-24
  • 2019-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多