简体   繁体   English

MongoDB带条件的嵌套文档查询

[英]MongoDB nested document queries with conditions

I'm trying to wrap my head around some more complex MongoDB queries. 我试图围绕一些更复杂的MongoDB查询工作。 I've read through a number of somewhat-related questions , but I haven't quite been able to figure out what would be the best approach for the situation I'm in. Say I'm trying to index a collection of DVD's with different club soccer matches recorded, and I've modeled the documents in the collection like the following (abbreviated): 我已经阅读了一些与问题相关的问题,但是我还无法弄清楚哪种方法对于遇到的情况是最好的。例如,我正在尝试用以下方法索引DVD的集合记录了各种俱乐部足球比赛,我对集合中的文档进行了建模,如下所示(略):

{ 
  "dvdId" : "10021", 
  "dateSubmitted" : ISODate("2015-11-17T15:42:21.248Z"),
  "featuredPlayerNames": [
    "Sam B. Clement", 
    "John C. Carter", 
    "Gabriel M. Malinowski", 
    "Jimmy I. Vincent", 
    "George L. Spears", 
    "Roland M. Nelson", 
  ],
  "matches" : [ 
    { 
      "startTime" : 0,
      "winningTeamIndex": 0,
      "teams" : [ 
        { 
          "teamName": "Hornets",
          "players" : [ 
            { 
              "name" : "Sam B. Clement", 
              "position" : "striker" 
            }, 
            { 
              "name" : "John C. Carter", 
              "position" : "halfback" 
            },
          ] 
        }, 
        { 
          "teamName": "Hurricanes",
          "players" : [ 
            { 
              "name" : "Gabriel M. Malinowski", 
              "position" : "fullback" 
            }, 
            { 
              "name" : "Jimmy I. Vincent", 
              "position" : "keeper" 
            },
          ] 
        } 
      ] 
    },
    { 
      "startTime": 5602,
      "winningTeamIndex": 1,
      "teams" : [ 
        { 
          "teamName": "Raiders",
          "players" : [ 
            { 
              "name" : "Sam B. Clement", 
              "position" : "halfback" 
            }, 
            { 
              "name" : "George L. Spears", 
              "position" : "striker" 
            },
          ] 
        }, 
        { 
          "teamName": "Hurricanes",
          "players" : [ 
            { 
              "name" : "Roland M. Nelson", 
              "position" : "striker" 
            }, 
            { 
              "name" : "Jimmy I. Vincent", 
              "position" : "keeper" 
            },
          ] 
        } 
      ] 
    },    
  ], 
}

What I've done so far. 到目前为止我所做的。 I've figured out how to get it to do some simple operations on the first-level properties and arrays, such as returning DVD's featuring a player of interest and/or another player of interest; 我已经弄清楚了如何使它在第一级属性和数组上执行一些简单的操作,例如返回包含感兴趣的播放器和/或另一个感兴趣的播放器的DVD。 eg, db.dvds.find({featuredPlayerNames: {$in: ['Sam B. Clement', 'John C. Carter']}}); 例如db.dvds.find({featuredPlayerNames: {$in: ['Sam B. Clement', 'John C. Carter']}}); .

Where I need help. 我需要帮助的地方。 I'm now trying to figure out how I would query the Mongo database with more complex operations, such as return documents containing match(es) featuring the following conditions: 我现在试图弄清楚如何用更复杂的操作来查询Mongo数据库,例如包含具有以下条件的匹配项的返回文档:

  • a team of interest is the winning team 一个感兴趣的团队就是胜利的团队
  • a player of interest AND another player of interest on the same team 一个感兴趣的球员和另一个感兴趣的球员在同一支球队
  • a player of interest AND another player of interest on different teams 感兴趣的球员和不同球队的另一个感兴趣的球员
  • a player of interest on the winning team 获胜团队感兴趣的球员
  • a player of interest playing a position of interest 感兴趣的玩家扮演感兴趣的位置
  • a player of interest playing a position of interest AND a player of interest playing a position of interest on different teams 感兴趣的球员在不同球队上的位置,感兴趣的球员在不同球队上的位置

What would be the best approach to accomplish advanced queries such as these? 完成此类高级查询的最佳方法是什么? After wandering in the documentation and from my reading of similar questions ( 1 2 3 4 5 6 7 8 9 10 11 12* 13* ), I've found I may need to use $elemMatch , $cond , $in , $all , $match , $unwind , $group , and/or the aggregation framework, but in addition to being unfamiliar with many of these, I also saw a lot of different opinions and approaches, and none that really seemed to combine nested queries with specific conditions (like a player on the winning team or players on different teams). 在文档中徘徊,并阅读了类似的问题( 1 2 3 4 5 6 7 8 9 10 11 12 * 13 * )后,我发现可能需要使用$elemMatch$cond$in$all$match$unwind$group和/或聚合框架,但除了不熟悉其中的许多方法外,我还看到了许多不同的观点和方法,而且似乎并没有真正将嵌套查询与特定查询结合在一起的方法。条件(例如获胜球队的球员或不同球队的球员)。

Now I could probably learn to do most of these given a push in the right direction. 现在,只要朝着正确的方向发展,我就可以学会做大部分的事情。 I'm also open to remodeling the structure of the data here if it seems something would work better for my case (provided I would be able to add more teams to a match as in 2v2v2). 如果看来某些情况更适合我的情况,我也愿意在这里重塑数据的结构(前提是我能够像2v2v2那样增加更多球队参加比赛)。

Thank you! 谢谢!

In general it is faster and easier to structure your data in a manner that allows simple queries than to write complicated queries. 通常,以允许简单查询的方式比编写复杂查询的方式更快,更轻松地构造数据。 Reformatting your data set might be a one-time cost, whereas a costly query might be executed millions of times. 重新格式化您的数据集可能是一次性的开销,而昂贵的查询可能会执行数百万次。

Your questions: 你的问题:

  • teamX is a winning team teamX是一支胜利的队伍
    • reformat the data to add matches.winningTeamName field 重新格式化数据以添加matchs.winningTeamName字段
    • { matches.winningTeamName: teamX } {matchs.winningTeamName:teamX}
    • or reformat the data to add matches.teams.winner field 或重新格式化数据以添加matchs.teams.winner字段
    • { matches.teams: { $elemMatch: { winner: true, teamName: teamX } } } {matchs.teams:{$ elemMatch:{获胜者:true,teamName:teamX}}}
  • playerX and playerY on same team 同一团队的玩家X和玩家Y
    • matches.teams: { $and: [ {players.name: playerX}, {players.name, playerY} ] } matchs.teams:{$ and:[{players.name:playerX},{players.name,playerY}]}
    • Or reformat the data to add matches.teams.playerList field 或重新格式化数据以添加matchs.teams.playerList字段
    • { matches.teams.playerList: { $all: [playerX, playerY] } } {matchs.teams.playerList:{$ all:[playerX,playerY]}}
  • playerX and playerY on different teams 不同团队的playerX和playerY
    • not sure, I think you can do this with a combination of $and and $not but without having the db set up I'd be guessing. 不确定,我想您可以结合使用$ and和$ not来完成此操作,但是如果没有设置数据库,我会猜测。
  • playerX on winning team 获胜队伍上的playerX
    • reformat the data to add matches.teams.winner field 重新格式化数据以添加matchs.teams.winner字段
    • { matches.teams: { $elemMatch: { winner: true, players.name: playerX } } } {matchs.teams:{$ elemMatch:{获胜者:true,players.name:playerX}}}
  • playerX playing positionX playerX比赛位置X
    • { matches.teams.players: { $elemMatch: { name: playerX, position: positionX} } } {matchs.teams.players:{$ elemMatch:{名称:playerX,位置:positionX}}}
  • again with the different teams... 再次与不同的团队...

Hope that helps... 希望有帮助...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM