MongoDB嵌入式文档的区别和过滤器

时间:2019-12-28 08:37:46

标签: mongodb mongodb-query

我有以下数据:

{ "_id" : ObjectId("5b82958518aae6c2d2cd429e"), "troops" : [ { "name" : "Baby Dragon", "village" : "builderBase" }, { "name" : "Beta Minion", "village" : "builderBase" }, { "name" : "Bomber", "village" : "builderBase" }, { "name" : "Boxer Giant", "village" : "builderBase" }, { "name" : "Cannon Cart", "village" : "builderBase" }, { "name" : "Night Witch", "village" : "builderBase" }, { "name" : "Raged Barbarian", "village" : "builderBase" }, { "name" : "Sneaky Archer", "village" : "builderBase" }, { "name" : "Archer", "village" : "home" }, { "name" : "Baby Dragon", "village" : "home" }, { "name" : "Balloon", "village" : "home" }, { "name" : "Barbarian", "village" : "home" }, { "name" : "Bowler", "village" : "home" }, { "name" : "Dragon", "village" : "home" }, { "name" : "Giant", "village" : "home" }, { "name" : "Goblin", "village" : "home" }, { "name" : "Golem", "village" : "home" }, { "name" : "Healer", "village" : "home" }, { "name" : "Hog Rider", "village" : "home" }, { "name" : "Lava Hound", "village" : "home" }, { "name" : "Miner", "village" : "home" }, { "name" : "Minion", "village" : "home" }, { "name" : "P.E.K.K.A", "village" : "home" }, { "name" : "Valkyrie", "village" : "home" }, { "name" : "Wall Breaker", "village" : "home" }, { "name" : "Witch", "village" : "home" }, { "name" : "Wizard", "village" : "home" } ] }
{ "_id" : ObjectId("5b82958518aae6c2d2cd42a1"), "troops" : [ { "name" : "Baby Dragon", "village" : "builderBase" }, { "name" : "Beta Minion", "village" : "builderBase" }, { "name" : "Bomber", "village" : "builderBase" }, { "name" : "Boxer Giant", "village" : "builderBase" }, { "name" : "Cannon Cart", "village" : "builderBase" }, { "name" : "Raged Barbarian", "village" : "builderBase" }, { "name" : "Sneaky Archer", "village" : "builderBase" }, { "name" : "Archer", "village" : "home" }, { "name" : "Baby Dragon", "village" : "home" }, { "name" : "Balloon", "village" : "home" }, { "name" : "Barbarian", "village" : "home" }, { "name" : "Bowler", "village" : "home" }, { "name" : "Dragon", "village" : "home" }, { "name" : "Electro Dragon", "village" : "home" }, { "name" : "Giant", "village" : "home" }, { "name" : "Goblin", "village" : "home" }, { "name" : "Golem", "village" : "home" }, { "name" : "Healer", "village" : "home" }, { "name" : "Hog Rider", "village" : "home" }, { "name" : "Ice Golem", "village" : "home" }, { "name" : "Lava Hound", "village" : "home" }, { "name" : "Miner", "village" : "home" }, { "name" : "Minion", "village" : "home" }, { "name" : "P.E.K.K.A", "village" : "home" }, { "name" : "Valkyrie", "village" : "home" }, { "name" : "Wall Breaker", "village" : "home" }, { "name" : "Witch", "village" : "home" }, { "name" : "Wizard", "village" : "home" } ] }

并且我正在尝试从home troops.village中获得不同的值。基本的(未经过滤的)distinct返回预期结果(troops中的所有值,与troops.village无关):

> db.players.distinct("troops.name")
["Archer", "Baby Dragon", "Balloon", "Barbarian", "Beta Minion", "Bomber", "Bowler", "Boxer Giant", "Cannon Cart", "Dragon", "Giant", "Goblin", "Golem", "Healer", "Hog Rider", "Lava Hound", "Miner", "Minion", "Night Witch", "P.E.K.K.A", "Raged Barbarian", "Sneaky Archer", "Valkyrie", "Wall Breaker", "Witch", "Wizard", "Electro Dragon", "Ice Golem", "Battle Blimp", "Drop Ship", "Hog Glider", "Stone Slammer", "Super P.E.K.K.A", "Wall Wrecker", "Yeti", "Siege Barracks"]

我尝试了以下操作:

> db.players.distinct("troops.name", {"village": "home"})
// This returns an empty set

我也尝试过:

> db.players.distinct("troops.name", {"troops.village": "home"})
// This returns the exact same result set as distinct unfiltered, above.

1 个答案:

答案 0 :(得分:3)

当您尝试将它用于子文档时,distinct"query"部分适用于文档级别,因此在这种情况下将无法使用。您需要使用$filter$setUnion来在单个文档中获取不同的,经过过滤的值:

db.collection.aggregate([
    { 
        $project: {
            distinctHomeNames: { $setUnion: { $filter: { input: "$troops", cond: { $eq: [ "$$this.village", "home" ] } } } }
        }
    }
])

Mongo Playground

编辑:带有$map的版本仅打印名称here