0

我有一个名为 season 的集合,如下所示:

[ 
  { 
    week: 1,
    matchups: [ 
        {
            home : ObjectId("1"),
            away : ObjectId("2")
        },
        {
            home : ObjectId("3"),
            away : ObjectId("4")
        },

    ],
    _id: 50fc50c9ce87149ee3000007 
  },
  { 
    week: 2,
    matchups: [ 
        {
            home : ObjectId("3"),
            away : ObjectId("1")
        },
        {
            home : ObjectId("2"),
            away : ObjectId("4")
        },
    ],
    _id: 50fc50c9ce87149ee3000008 
  }
]

我正在尝试获取主队或客队为 ObjectId("1") 的所有比赛。我希望返回看起来像这样:

[ 
  { 
    week: 1,
    matchups: [ 
        {
            home : ObjectId("1"),
            away : ObjectId("2")
        }

    ],
    _id: 50fc50c9ce87149ee3000007 
  },
  { 
    week: 2,
    matchups: [ 
        {
            home : ObjectId("3"),
            away : ObjectId("1")
        }
    ],
    _id: 50fc50c9ce87149ee3000008 
  }
]

是否可以在 db.season.find() 上使用此结果?

4

2 回答 2

2

只要您最多matchups匹配一个潜在元素,就可以使用$elemMatch投影运算符来执行此操作:

db.seasons.find(
    {$or: [{'matchups.home': ObjectId("1")},{'matchups.away': ObjectId("1")}]}, 
    {week: 1, matchups: {
        $elemMatch: {$or: [{home: ObjectId("1")},{away: ObjectId("1")}]}
    }});

与 Wes 关于ObjectId("1").

于 2013-01-21T02:55:27.973 回答
1

不是使用 .find,而是使用 .aggregate:

db.seasons.aggregate(
  {$match:{$or:[{"matchups.home":ObjectId("1")}, {"matchups.away":ObjectId("1")}]}}, 
  {$unwind:"$matchups"}, 
  {$match:{$or:[{"matchups.home":ObjectId("1")}, {"matchups.away":ObjectId("1")}]}}, 
  {$group:{_id:"$_id", week:{$first:"$week"}, matchups:{$addToSet:"$matchups"}}});
  1. 第一个匹配过滤器的那些有你的团队(如果有一些不包含你的团队的记录将使其余的更有效率)
  2. 放松对决
  3. 第二场比赛过滤器仅适用于拥有您的团队的人
  4. 组再次重建您的记录

限制是带有聚合的文档大小。希望这可以帮助。

使用 .find 可以做的最好的事情是第一次匹配,然后在应用程序端过滤匹配,AFAIK。

此外, ObjectId("1") 无效,仅供参考。

于 2013-01-21T02:27:44.003 回答