使用mongo查询修改或展开深层嵌套数组

时间:2014-05-20 16:40:19

标签: mongodb aggregation-framework

在创建了自己的聚合管道之后,我得出了以下结果:

[
    {
      "_id": "53712c7238b8d900008ef71c",
      "address": [
        {
          "_id": "53712c7238b8d900008ef71b",
          "phoneNumber": "4092348294",
          ...
        }
      ],
      "name": "TestDealer",
      "vehicles": [
        {
          "_id": "53712fa138b8d900008ef720",
          "createdAt": "2014-05-12T20:08:00.000Z",
          "tags": [
            "vehicle"
          ],
          "opts": [
            {
              "_id": "53712fa138b8d900008ef71e",
              "hasSunroof": false,
              ...
            }
          ],
          "listed": true,
          "disclosures": [
            {
              "_id": "53712fa138b8d900008ef71f",
              "waterDamage": false,
              ...
            }
          ],
          "details": [
            {
              "_id": "53712fa138b8d900008ef71d",
              "year": 2007,
              ...
            }
          ]
        },
        {
          "_id": "5373c6439058859af7904a17",
          "createdAt": "2014-05-14T19:17:00.000Z",
          "tags": [
            "vehicle"
          ],
          "opts": [
            {
              "_id": "5373c6439058859af7904a15",
              "hasSunroof": false,
              ....
              "other": []
            }
          ],
          "listed": true,
          "disclosures": [
            {
              "_id": "5373c6439058859af7904a16",
              "waterDamage": false,
              ...
            }
          ],
          "details": [
            {
              "_id": "5373c6439058859af7904a14",
              "year": 2013,
              ...
            }
          ]
        }
      ]
    }
  ]

如您所见,vehicles是一系列遵循特定架构的子文档(车辆):

  • 详细信息:details subdocs
  • 的数组
  • opts:opts subdocs
  • 的数组
  • 披露:disclosures subdocs
  • 的数组

对于detailsdisclosuresopts中的每一个,我想返回数组中的第一个子数据块而不是数组。但是,我不知道从哪里开始。我不能真正放松车辆,因为它可能是空的。

以下是我的最终数据:

[
    {
      "_id": "53712c7238b8d900008ef71c",
      "address": [
        {
          "_id": "53712c7238b8d900008ef71b",
          "phoneNumber": "4092348294",
          ...
        }
      ],
      "name": "TestDealer",
      "vehicles": [
        {
          "_id": "53712fa138b8d900008ef720",
          "createdAt": "2014-05-12T20:08:00.000Z",
          "tags": [
            "vehicle"
          ],
          "opts": {
              "_id": "53712fa138b8d900008ef71e",
              "hasSunroof": false,
              ...
          },
          "listed": true,
          "disclosures": {
              "_id": "53712fa138b8d900008ef71f",
              "waterDamage": false,
              ...
          },
          "details": {
              "_id": "53712fa138b8d900008ef71d",
              "year": 2007,
              ...
          }
        },
        {
          "_id": "5373c6439058859af7904a17",
          "createdAt": "2014-05-14T19:17:00.000Z",
          "tags": [
            "vehicle"
          ],
          "opts": {
              "_id": "5373c6439058859af7904a15",
              "hasSunroof": false,
              ....
              "other": []
          },
          "listed": true,
          "disclosures": {
              "_id": "5373c6439058859af7904a16",
              "waterDamage": false,
              ...
          },
          "details": {
              "_id": "5373c6439058859af7904a14",
              "year": 2013,
              ...
          }
        }
      ]
    }
  ]

修改

以下是我获取数据的聚合(在CoffeeScript中):

      {
        $match:
          _id: ObjectId(params.id)
      }
      {
        $unwind: '$inventories'
      }
      {
        $match:
          'inventories._id': 'active'
      }
      {
        $redact:
          $cond:
            if:
              $eq:['$listed',false]
            then: '$$PRUNE'
            else: '$$DESCEND'
      }
      {
        $project:
          address: 1
          name: '$dealerName'
          email: '$_id.email'
          vehicles: '$inventories.vehicles'
      }

以及原始数据:

{ "_id" : ObjectId( "53712c7238b8d900008ef71c" ),
  "email" : "test@test.com",
  "createdAt" : Date( 1399925280000 ),
  "password" : "$2a$10$3dhicJuONkXeI9mQflXF0.JftAx7mLQaY2./6a3O7xdrs5qfH2zMW",
  "firstName" : "TestName",
  "lastName" : "testName",
  "dealerName" : "TestDealer",
  "dealerType" : "Franchised Dealer",
  "emailIsVerified" : false,
  "lastLoggedInAt" : Date( 1400247300000 ),
  "expiresAt" : Date( 4524062882000 ),
  "deletedAt" : null,
  "updatedAt" : Date( 1400251500000 ),
  "inventories" : [ 
    { "title" : "activeInventory",
      "_id" : "active",
      "vehicles" : [ 
        { "_id" : ObjectId( "53712fa138b8d900008ef720" ),
          "createdAt" : Date( 1399925280000 ),
          "tags" : [ 
            "vehicle" ],
          "opts" : [ 
            { "_id" : ObjectId( "53712fa138b8d900008ef71e" ),
              "hasSunroof" : false,
              "hasSnowTires" : false,
              "hasPowerWindows" : false,
              "hasNavigationSystem" : false,
              "hasManuals" : false,
              "hasMags" : false,
              "hasLeather" : false,
              "hasKeylessEntry" : false,
              "hasHeatedSeats" : false,
              "hasDvdSystem" : false,
              "hasAirConditioning" : false,
              "has2SetsOfKeys" : false,
              "other" : [] } ],
          "listed" : true,
          "disclosures" : [ 
            { "_id" : ObjectId( "53712fa138b8d900008ef71f" ),
              "waterDamage" : false,
              "vehicleLien" : false,
              "usVehicle" : false,
              "totalLossByInsurer" : false,
              "theftOrRecovery" : false,
              "taxiOrLimo" : false,
              "structuralPartsAreDamagedOrAlteredOrRepaired" : false,
              "suspensionOrSubFrameNeedsRepair" : false,
              "repainted" : false,
              "previousDamageExceeding3k" : false,
              "powerTrainNeedsRepair" : false,
              "policeCruiser" : false,
              "outOfProvinceOrState" : false,
              "originalOwner" : false,
              "originalManufacturerVinPlate" : false,
              "originalSpecificationsChanged" : false,
              "odometerRolledBackOrReplaced" : false,
              "manufacturerWarrantyCancelled" : false,
              "manufacturerBadgesChanged" : false,
              "fuelSystemNeedsRepair" : false,
              "fireDamage" : false,
              "engineNeedsRepair" : false,
              "emergencyVehicle" : false,
              "electricalSystemNeedsRepair" : false,
              "dailyRental" : false,
              "computerNeedsRepair" : false,
              "antiLockBrakesDamagedOrInoperable" : false,
              "airbagIsMissingOrInoperable" : false,
              "airConditioningNeedsRepair" : false } ],
          "details" : [ 
            { "_id" : ObjectId( "53712fa138b8d900008ef71d" ),
              "year" : 2007,
              "vin" : "JN8AZ08W27W649264",
              "trim" : "SE",
              "transmission" : "Automatic",
              "price" : 132123,
              "model" : "Murano 4D Utility AWD",
              "mileageReading" : 125000,
              "make" : "Nissan",
              "interiorColor" : "Black",
              "history" : "Carproof Verified ($40.00)",
              "hasAccident" : false,
              "fuelType" : "Biodiesel",
              "exteriorColor" : "Blue",
              "driveTrain" : "FWD",
              "description" : "dsadas",
              "cylinders" : 4,
              "mileageType" : "kms" } ] }, 
        { "_id" : ObjectId( "53713bfc1429925f0faf79d0" ),
          "createdAt" : Date( 1399929780000 ),
          "tags" : [ 
            "vehicle" ],
          "opts" : [ 
            { "_id" : ObjectId( "53713bfc1429925f0faf79ce" ),
              "hasSunroof" : false,
              "hasSnowTires" : false,
              "hasPowerWindows" : false,
              "hasNavigationSystem" : false,
              "hasManuals" : false,
              "hasMags" : false,
              "hasLeather" : false,
              "hasKeylessEntry" : false,
              "hasHeatedSeats" : false,
              "hasDvdSystem" : false,
              "hasAirConditioning" : false,
              "has2SetsOfKeys" : false,
              "other" : [] } ],
          "listed" : false,
          "disclosures" : [ 
            { "_id" : ObjectId( "53713bfc1429925f0faf79cf" ),
              "waterDamage" : false,
              "vehicleLien" : false,
              "usVehicle" : false,
              "totalLossByInsurer" : false,
              "theftOrRecovery" : false,
              "taxiOrLimo" : false,
              "structuralPartsAreDamagedOrAlteredOrRepaired" : false,
              "suspensionOrSubFrameNeedsRepair" : false,
              "repainted" : false,
              "previousDamageExceeding3k" : false,
              "powerTrainNeedsRepair" : false,
              "policeCruiser" : false,
              "outOfProvinceOrState" : false,
              "originalOwner" : false,
              "originalManufacturerVinPlate" : false,
              "originalSpecificationsChanged" : false,
              "odometerRolledBackOrReplaced" : false,
              "manufacturerWarrantyCancelled" : false,
              "manufacturerBadgesChanged" : false,
              "fuelSystemNeedsRepair" : false,
              "fireDamage" : false,
              "engineNeedsRepair" : false,
              "emergencyVehicle" : false,
              "electricalSystemNeedsRepair" : false,
              "dailyRental" : false,
              "computerNeedsRepair" : false,
              "antiLockBrakesDamagedOrInoperable" : false,
              "airbagIsMissingOrInoperable" : false,
              "airConditioningNeedsRepair" : false } ],
          "details" : [ 
            { "_id" : ObjectId( "53713bfc1429925f0faf79cd" ),
              "year" : 2007,
              "vin" : "JN8AZ08W27W649264",
              "trim" : "SE",
              "transmission" : "Manual",
              "price" : 13241234,
              "model" : "Murano 4D Utility AWD",
              "mileageReading" : 1312312,
              "make" : "Mercedes-Benz",
              "interiorColor" : "Black",
              "history" : "Carproof Claims ($25.00)",
              "hasAccident" : true,
              "fuelType" : "Diesel",
              "exteriorColor" : "Black",
              "driveTrain" : "RWD",
              "description" : "werwe",
              "cylinders" : 4,
              "mileageType" : "kms" } ] }, 
        { "_id" : ObjectId( "5373c6439058859af7904a17" ),
          "createdAt" : Date( 1400095020000 ),
          "tags" : [ 
            "vehicle" ],
          "opts" : [ 
            { "_id" : ObjectId( "5373c6439058859af7904a15" ),
              "hasSunroof" : false,
              "hasSnowTires" : false,
              "hasPowerWindows" : false,
              "hasNavigationSystem" : false,
              "hasManuals" : false,
              "hasMags" : false,
              "hasLeather" : false,
              "hasKeylessEntry" : false,
              "hasHeatedSeats" : false,
              "hasDvdSystem" : false,
              "hasAirConditioning" : false,
              "has2SetsOfKeys" : false,
              "other" : [] } ],
          "listed" : true,
          "disclosures" : [ 
            { "_id" : ObjectId( "5373c6439058859af7904a16" ),
              "waterDamage" : false,
              "vehicleLien" : false,
              "usVehicle" : false,
              "totalLossByInsurer" : false,
              "theftOrRecovery" : false,
              "taxiOrLimo" : false,
              "structuralPartsAreDamagedOrAlteredOrRepaired" : false,
              "suspensionOrSubFrameNeedsRepair" : false,
              "repainted" : false,
              "previousDamageExceeding3k" : false,
              "powerTrainNeedsRepair" : false,
              "policeCruiser" : false,
              "outOfProvinceOrState" : false,
              "originalOwner" : false,
              "originalManufacturerVinPlate" : false,
              "originalSpecificationsChanged" : false,
              "odometerRolledBackOrReplaced" : false,
              "manufacturerWarrantyCancelled" : false,
              "manufacturerBadgesChanged" : false,
              "fuelSystemNeedsRepair" : false,
              "fireDamage" : false,
              "engineNeedsRepair" : false,
              "emergencyVehicle" : false,
              "electricalSystemNeedsRepair" : false,
              "dailyRental" : false,
              "computerNeedsRepair" : false,
              "antiLockBrakesDamagedOrInoperable" : false,
              "airbagIsMissingOrInoperable" : false,
              "airConditioningNeedsRepair" : false } ],
          "details" : [ 
            { "_id" : ObjectId( "5373c6439058859af7904a14" ),
              "year" : 2013,
              "vin" : "12345678901234567",
              "trim" : "SE",
              "transmission" : "Automatic",
              "price" : 13564,
              "model" : "Red",
              "mileageReading" : 13453,
              "make" : "Daihatsu",
              "interiorColor" : "Black",
              "history" : "Carproof Verified ($40.00)",
              "hasAccident" : true,
              "fuelType" : "Diesel",
              "exteriorColor" : "Black",
              "driveTrain" : "FWD",
              "description" : "wrw",
              "cylinders" : 3,
              "mileageType" : "kms" } ] } ],
      "tags" : [ 
        "inventory", 
        "active", 
        "vehicles" ] }, 
    { "title" : "soldInventory",
      "_id" : "sold",
      "vehicles" : [],
      "tags" : [ 
        "inventory", 
        "sold", 
        "vehicles" ] }, 
    { "title" : "deletedInventory",
      "_id" : "deleted",
      "vehicles" : [],
      "tags" : [ 
        "inventory", 
        "deleted", 
        "vehicles" ] } ],
  "address" : [ 
    { "_id" : ObjectId( "53712c7238b8d900008ef71b" ),
      "phoneNumber" : "4092348294",
      "country" : "Canada",
      "zip" : "301111",
      "region" : "Quebec",
      "city" : "Montreal",
      "street2" : "Apt. 101",
      "street1" : "1213 Street",
      "additionalNumbers" : [] } ],
  "__v" : 3 }

1 个答案:

答案 0 :(得分:1)

如果你使用2.6(你必须使用$ redact),并且如果没有标签或opts,如果数组总是保证为空,你可以使用这种技术确保你不会丢失$unwind

时有空数组的车辆

$project阶段,为您要展开的所有数组添加以下内容以保留第一个元素:

opts:{$cond:{if:{$eq:[{$size:"$opts"},0]}, then:{$literal:[ "none" ]}, else:"$opts"}}

对于每个子阵列,您现在可以对第一个子阵列进行分组,然后再次为下一个子阵列重复。

你需要小心分别对每个阵列进行展开和重新分组以防止任何重复,如果你没有聚合其他东西,你可以在一个组中用尽可能多的$ unwinds进行因为有子阵列。