如何查询文档中对象的所有子对象?
How to query all children of an object within a document?
以三个文档为例
[
{
_id: '/players/c/cruzne02.shtml',
url: '/players/c/cruzne02.shtml',
name: 'Nelson Cruz',
image: 'https://www.baseball-reference.com/req/202108020/images/headshots/f/fea2f131_mlbam.jpg',
teams: {
MIL: [ 2005 ],
TEX: [
2006, 2007, 2007, 2008,
2008, 2009, 2009, 2010,
2010, 2011, 2011, 2012,
2012, 2013, 2013
],
BAL: [ 2014 ],
SEA: [
2015, 2016,
2016, 2017,
2017, 2018,
2018
],
MIN: [ 2019, 2020, 2020, 2021, 2021 ],
TBR: [ 2021 ]
}
},
{
_id: '/players/b/berrijo01.shtml',
url: '/players/b/berrijo01.shtml',
name: 'Jose Berrios',
image: 'https://www.baseball-reference.com/req/202108020/images/headshots/d/d94db113_mlbam.jpg',
teams: {
MIN: [
2016, 2017, 2017,
2018, 2018, 2019,
2019, 2020, 2020,
2021, 2021
],
TOR: [ 2021 ]
}
},
{
_id: '/players/m/mauerjo01.shtml',
url: '/players/m/mauerjo01.shtml',
name: 'Joe Mauer',
image: 'https://www.baseball-reference.com/req/202108020/images/headshots/4/43c69595_mlbam.jpg',
teams: {
MIN: [
2004, 2005, 2005, 2006, 2006,
2007, 2007, 2008, 2008, 2009,
2009, 2010, 2010, 2011, 2011,
2012, 2012, 2013, 2013, 2014,
2014, 2015, 2015, 2016, 2016,
2017, 2017, 2018, 2018
]
}
}
]
假设我想获得在 2010 年参加比赛的两名球员,这将是第一个和第三个文件。当我被提供了我正在寻找球员的年份时,我该如何写这个发现。我尝试寻找通配符和查询对象所有子项的方法,但在这种情况下,键并不总是匹配。
与 2010 年一样,第一个文档为 TEX:2010,第三个文档为 MIN:2010。谁能帮帮我?
查询
将团队转换为数组以拥有
[["MIL", [2005] ["TEX": [2006,2007,...]] ...]
reduce 从 false
开始,并检查 2010 是否是任何这些数组的第二个成员中的成员 [2005],[2006,2007,...]
等
如果它至少是其中一个数组的成员,则 reduce returns 为真,文档通过匹配阶段
适用于 1 个比赛阶段,而且速度很快
*你可以避免使用 $$result
和 $$t
但我用它们来给
reduce 参数的名称,您可以删除它们。
db.collection.aggregate([
{
"$match": {
"$expr": {
"$reduce": {
"input": {
"$map": {
"input": {
"$objectToArray": "$teams"
},
"as": "m",
"in": [
"$$m.k",
"$$m.v"
]
}
},
"initialValue": false,
"in": {
"$let": {
"vars": {
"result": "$$value",
"t": "$$this"
},
"in": {
"$cond": [
{
"$or": [
"$$result",
{
"$in": [
2010,
{
"$arrayElemAt": [
"$$t",
1
]
}
]
}
]
},
true,
false
]
}
}
}
}
}
}
}
])
查询(与上面几乎相同,没有任何额外的变量等)
db.collection.aggregate([
{
$match: {
$expr: {
$reduce: {
input: {
$objectToArray: "$teams"
},
initialValue: false,
in: {
$cond: [
{
$or: [
"$$value",
{
$in: [
2010,
"$$this.v"
]
}
]
},
true,
false
]
}
}
}
}
}
])
以三个文档为例
[
{
_id: '/players/c/cruzne02.shtml',
url: '/players/c/cruzne02.shtml',
name: 'Nelson Cruz',
image: 'https://www.baseball-reference.com/req/202108020/images/headshots/f/fea2f131_mlbam.jpg',
teams: {
MIL: [ 2005 ],
TEX: [
2006, 2007, 2007, 2008,
2008, 2009, 2009, 2010,
2010, 2011, 2011, 2012,
2012, 2013, 2013
],
BAL: [ 2014 ],
SEA: [
2015, 2016,
2016, 2017,
2017, 2018,
2018
],
MIN: [ 2019, 2020, 2020, 2021, 2021 ],
TBR: [ 2021 ]
}
},
{
_id: '/players/b/berrijo01.shtml',
url: '/players/b/berrijo01.shtml',
name: 'Jose Berrios',
image: 'https://www.baseball-reference.com/req/202108020/images/headshots/d/d94db113_mlbam.jpg',
teams: {
MIN: [
2016, 2017, 2017,
2018, 2018, 2019,
2019, 2020, 2020,
2021, 2021
],
TOR: [ 2021 ]
}
},
{
_id: '/players/m/mauerjo01.shtml',
url: '/players/m/mauerjo01.shtml',
name: 'Joe Mauer',
image: 'https://www.baseball-reference.com/req/202108020/images/headshots/4/43c69595_mlbam.jpg',
teams: {
MIN: [
2004, 2005, 2005, 2006, 2006,
2007, 2007, 2008, 2008, 2009,
2009, 2010, 2010, 2011, 2011,
2012, 2012, 2013, 2013, 2014,
2014, 2015, 2015, 2016, 2016,
2017, 2017, 2018, 2018
]
}
}
]
假设我想获得在 2010 年参加比赛的两名球员,这将是第一个和第三个文件。当我被提供了我正在寻找球员的年份时,我该如何写这个发现。我尝试寻找通配符和查询对象所有子项的方法,但在这种情况下,键并不总是匹配。
与 2010 年一样,第一个文档为 TEX:2010,第三个文档为 MIN:2010。谁能帮帮我?
查询
将团队转换为数组以拥有
[["MIL", [2005] ["TEX": [2006,2007,...]] ...]
reduce 从
false
开始,并检查 2010 是否是任何这些数组的第二个成员中的成员[2005],[2006,2007,...]
等 如果它至少是其中一个数组的成员,则 reduce returns 为真,文档通过匹配阶段适用于 1 个比赛阶段,而且速度很快
*你可以避免使用 $$result
和 $$t
但我用它们来给
reduce 参数的名称,您可以删除它们。
db.collection.aggregate([
{
"$match": {
"$expr": {
"$reduce": {
"input": {
"$map": {
"input": {
"$objectToArray": "$teams"
},
"as": "m",
"in": [
"$$m.k",
"$$m.v"
]
}
},
"initialValue": false,
"in": {
"$let": {
"vars": {
"result": "$$value",
"t": "$$this"
},
"in": {
"$cond": [
{
"$or": [
"$$result",
{
"$in": [
2010,
{
"$arrayElemAt": [
"$$t",
1
]
}
]
}
]
},
true,
false
]
}
}
}
}
}
}
}
])
查询(与上面几乎相同,没有任何额外的变量等)
db.collection.aggregate([
{
$match: {
$expr: {
$reduce: {
input: {
$objectToArray: "$teams"
},
initialValue: false,
in: {
$cond: [
{
$or: [
"$$value",
{
$in: [
2010,
"$$this.v"
]
}
]
},
true,
false
]
}
}
}
}
}
])