mongoose / mongodb查询没有相关记录的记录

时间:2014-04-25 04:11:58

标签: node.js mongodb mongoose

我有两个猫鼬模特。让我们调用一个模型foo和第二个模型栏。条形记录具有相关的foo记录和电子邮件地址。我希望我的api被传递一个电子邮件地址并返回一个没有使用该电子邮件地址创建的条形记录的foo记录列表。我怎么会用猫鼬做这个呢?

我知道我可以用SQL编写这个查询,但我一直在尝试学习一个没有sql db,因此mongo。

这是一个例子。我有2条foo记录和2条记录:

FOOS:

{name:"first foo"}
{name:"second foo"}

和我的酒吧记录:

{
    email:"requestEmail@example.com,
    foo_id:first_foo._id
}

{
    email:"someOther@example.com,
    foo_id:second_foo._id
}

我的api请求将通过电子邮件发送:requestEmail@example.com。在这种情况下,我想返回第二个foo(和任何其他foo记录),因为第一个foo在请求中有一个带有电子邮件的条形记录。

2 个答案:

答案 0 :(得分:3)

两次传球最容易做到这一点。首先,您应检索所有Bar对象,然后根据它们过滤Foo对象。我没有node.js编译器,因此我的代码包含一些错误(我可以在白天稍后编辑它,但是你会得到图片)。

var findFooWOutBar = function(theEmail)
{
  Bar.find({email: theEmail}, function(err,docs)
  {
    if(err)
    {
      console.log(err);
      return
    }
    else
    {
      var barIds=[];
      docs.forEach(function(bar) //fetching all of the bars with the email
      {
        barIds.push(bar._id);//or whatever you are using as a reference 
      });

      //nin means not in
      Foo.find().nin('barRef', barIds).exec(function(err,foos)
      {
        //process your Foo results (foos) here
      }); //have not tested this, but according to the docs it should go something like this      
    }
  });

}

所以基本上,也许某些东西并不完全正确,但你需要一个Bar ID数组(或你正在使用的其他参考键)并将它与nin(不在)的使用相结合。

答案 1 :(得分:0)

我认为你应该先改变你的架构。 bar模式可以定义如下:

var Schema = require('mongoose').Schema;
var barSchema = new Schema({
    email: {
        type: String,
        unique: true
    },
    fooId: {
    type: Schema.Types.ObjectId
    },
});

现在,fooSchema可以定义如下:

var Schema = require('mongoose').Schema;
var fooSchema = new Schema({ 
    name: {
       type : String
    }   
});

好的,我们已经有了架构。现在我们可以定义模型并以解决方案的方式工作。

var model = require('mongoose').model;
var foo = model('Foo', fooSchema);
var bar = model('Bar', barSchema);

function fooWithNoBar(email) {
    var conditions = {
        email: email
    }
    bar.find(conditions, function (err, data) {
        if (err) {
            console.log(err);
            return
        } else {
            var barIds = [];
            data.forEach(function (bar) {
                barIds.push(bar._id); 
            });
            conditions = {
                    _id: {
                        $nin: barIds
                    }
                }
            foo.find(conditions, function (err, data) {
                console.log("foo records that do not have a bar record created with that email address: ", data);
            });
        }
    });
}

注意:我已经从Aleksandar的答案中复制了一些代码。