Получить отношение родитель-потомок с агрегацией mongodb - PullRequest
1 голос
/ 23 мая 2019

У меня есть одна коллекция под названием "местоположение". в этой коллекции все дочерние и родительские коллекции являются магазинами. Теперь я хочу создать запрос, который возвращает меня от родительской строки к разделенной запятыми.

Коллекция

businessId: { type: mongoose.Schema.Types.ObjectId, ref: 'admin' },
parentId: { type: mongoose.Schema.Types.ObjectId, ref: 'location' },
name: { type: String },
image: { type: String },
imageManipulation: { type: String },
locationColor: [{ range: { type: String }, color: { type: String } }],
area: {},
settings: {},
status: { type: String, enum: [0, 1], default: 1 },
isChild: { type: String, enum: [0, 1] },
parentPosition: { type: String }

В приведенной выше коллекции вы можете увидеть поле parentId. если местоположение является дочерним, то оно имеет parentId. если местоположение является родительским, то parentId будет нулевым. родительское местоположение может N уровня дочернее местоположение.

Сбор данных

[{
    "_id": ObjectId("5ce4f84547e90a0b9c3c4763"),
    "name": "Test",
    "settings": {
        "zoom": "3",
        "positionX": "69",
        "positionY": "69",
        "width": "500",
        "height": "334"
    },
    "parentId": null,
    "image": "1558509637101.jpg",
    "status": "0",
    "businessId": ObjectId("5cbd61dc3b56b902284ea388"),
    "locationColor": [],
    "updatedAt": ISODate("2019-05-22T12:59:26.013Z"),
    "createdAt": ISODate("2019-05-22T07:20:37.112Z"),
    "__v": 0
},

{
    "_id": ObjectId("5ce50caf09359e1b8ccf5c79"),
    "name": "Test sub 1",
    "settings": {
        "zoom": "3",
        "positionX": "48",
        "positionY": "3",
        "width": "500",
        "height": "334"
    },
    "area": "",
    "parentId": ObjectId("5ce4f84547e90a0b9c3c4763"),
    "image": "1558514863396.jpg",
    "status": "0",
    "businessId": ObjectId("5cbd61dc3b56b902284ea388"),
    "locationColor": [],
    "updatedAt": ISODate("2019-05-22T12:59:21.883Z"),
    "createdAt": ISODate("2019-05-22T08:47:43.421Z"),
    "__v": 0
},
{
    "_id": ObjectId("5ce53977e46da33e6cfdd9d1"),
    "name": "Test Sub 2",
    "settings": {
        "zoom": "5",
        "positionX": "0",
        "positionY": "0",
        "width": "500",
        "height": "334"
    },
    "area": "",
    "parentId": ObjectId("5ce50caf09359e1b8ccf5c79"),
    "image": "1558526327126.jpg",
    "businessId": ObjectId("5cbd61dc3b56b902284ea388"),
    "locationColor": [],
    "updatedAt": ISODate("2019-05-22T11:58:47.147Z"),
    "createdAt": ISODate("2019-05-22T11:58:47.147Z"),
    "__v": 0
}]

Ожидаемый результат

Test, Test sub 1, Test Sub 2

Ожидаемый результат в формате JSON

[{
    "_id": ObjectId("5ce4f84547e90a0b9c3c4763"),
    "name": "Test",
},
{
    "_id": ObjectId("5ce50caf09359e1b8ccf5c79"),
    "name": "Test, Test sub 1",
},
{
    "_id": ObjectId("5ce53977e46da33e6cfdd9d1"),
    "name": "Test, Test sub 1, Test Sub 2",
}]

1 Ответ

1 голос
/ 23 мая 2019

В основном вам нужно $graphLookup для рекурсивного цикла в той же коллекции.

db.location.aggregate([
  { "$graphLookup": {
    "from": "location",
    "startWith": "$parentId",
    "connectFromField": "parentId",
    "connectToField": "_id",
    "as": "parent"
  }},
  { "$project": {
    "name": {
      "$concat": [
        "$name",
        { "$reduce": {
          "input": "$parent",
          "initialValue": "",
          "in": { "$concat": [",", "$$this.name", "$$value"] }
        }}
      ]
    }
  }}
])

Который выдаст

[
  {
    "_id": ObjectId("5ce4f84547e90a0b9c3c4763"),
    "name": "Test"
  },
  {
    "_id": ObjectId("5ce50caf09359e1b8ccf5c79"),
    "name": "Test sub 1,Test"
  },
  {
    "_id": ObjectId("5ce53977e46da33e6cfdd9d1"),
    "name": "Test Sub 2,Test sub 1,Test"
  }
]

MongoPlayground

...