首页 > 解决方案 > MongoDB 按数组值聚合列表

问题描述

它如何通过记录数组的值与子查询进行列表排序我希望在 mongo 端 models.js中执行最佳查询

new ms.Schema({
        name : {type: String,required: true,unique:true},
        display_name: {type: String,required: true,unique:true},
        url: {type: String,default:'' },
        icon: {type: String,default :'no.png' },
        assets : {type:Array,default : ['BTCUSDT']},
        active: {type: Boolean, default : true},
    })

mongodb的记录在这里

{
    "_id" : ObjectId("5e9e78c477b1c7a1bfc4978c"),
    "url" : "https://bitso.com/",
    "active" : false,
    "name" : "bitso",
    "display_name" : "Bitso",
    "icon" : "Bitso.png",
    "__v" : 0,
    "seq" : 888,
    "assets" : [
        "BTCUSDT",
        "ETHUSDT",
        "LTCUSDT"
    ]
},
{
    "_id" : ObjectId("5e9e78c377b1c7a1bfc4978a"),
    "url" : "https://www.fybsg.com/",
    "active" : false,
    "name" : "fybsg",
    "display_name" : "FYB-SG",
    "icon" : "FYB-SG.png",
    "__v" : 0,
    "seq" : 888,
    "assets" : [
        "BTCUSDT",
        "ETHUSDT"
    ]
},
{
    "_id" : ObjectId("5e9e78c377b1c7a1bfc49789"),
    "url" : "https://hitbtc.com/",
    "active" : true,
    "name" : "hitbtc",
    "display_name" : "Hitbtc",
    "icon" : "Hitbtc.png",
    "__v" : 0,
    "seq" : 99,
    "assets" : [
        "BCCUSDT"
    ]
},
{
    "_id" : ObjectId("5e9e78c077b1c7a1bfc49787"),
    "url" : "https://blockchain.io/",
    "active" : false,
    "name" : "blockchainio",
    "display_name" : "Blockchain.io",
    "icon" : "Blockchain.io.png",
    "__v" : 0,
    "seq" : 999,
    "assets" : [
        "BTCUSDT",
        "ETHUSDT"
    ]
},

db.markets.aggregate([...])

如果可能的话,我如何从 mongo 记录中导出结果;否则我必须使用什么算法

我需要这样的数据

[
BTCUSDT : { which record assets have BTCUSDT listings },
ETHUSDT : { which record assets have BTCUSDT  listings},  
...

]

标签: mongodbaggregate

解决方案


您需要使用stageassets对每个文档进行平面数组,然后按此字段对它们进行分组:$unwind

db.markets.aggregate([
  {
    $unwind: "$assets"
  },
  {
    $group: {
      _id: "$assets",
      recordId: {
        $push: "$_id"
      }
    }
  }
])

你的输出将是:

[
  {
    "_id": "BCCUSDT",
    "recordId": [
      "5e9e78c377b1c7a1bfc49789"
    ]
  },
  {
    "_id": "BTCUSDT",
    "recordId": [
      "5e9e78c477b1c7a1bfc4978c",
      "5e9e78c377b1c7a1bfc4978a",
      "5e9e78c077b1c7a1bfc49787"
    ]
  },
  {
    "_id": "LTCUSDT",
    "recordId": [
      "5e9e78c477b1c7a1bfc4978c"
    ]
  },
  {
    "_id": "ETHUSDT",
    "recordId": [
      "5e9e78c477b1c7a1bfc4978c",
      "5e9e78c377b1c7a1bfc4978a",
      "5e9e78c077b1c7a1bfc49787"
    ]
  }
]

如果您只获得一个对象作为结果更方便,您可以另外按nullid 对它们进行分组,使用k,v属性将所有文档存储在数组中并替换单个文档的根:

  {
    $group: {
      _id: null,
      result: {
        $push: {
          k: "$_id",
          v: "$recordId"
        }
      }
    }
  },
  {
    $addFields: {
      result: {
        $arrayToObject: "$result"
      }
    }
  },
  {
    $replaceRoot: {
      newRoot: "$result"
    }
  }

整个查询的结果将是:

[
  {
    "BCCUSDT": [
      "5e9e78c377b1c7a1bfc49789"
    ],
    "BTCUSDT": [
      "5e9e78c477b1c7a1bfc4978c",
      "5e9e78c377b1c7a1bfc4978a",
      "5e9e78c077b1c7a1bfc49787"
    ],
    "ETHUSDT": [
      "5e9e78c477b1c7a1bfc4978c",
      "5e9e78c377b1c7a1bfc4978a",
      "5e9e78c077b1c7a1bfc49787"
    ],
    "LTCUSDT": [
      "5e9e78c477b1c7a1bfc4978c"
    ]
  }
]

推荐阅读