mongoDB Агрегирование и разделение двух полей - PullRequest
1 голос
/ 28 января 2020

У меня есть следующая схема MongoDB MongoDB Schema

То, что я хочу, это: взять цену за каждый мой счет и поделить на количество членов.

ie:

Следуя примеру, у меня есть счет с ценой = 60 и существует 2 участника, поэтому мне нужно значение цены / членов.

И у меня есть следующий маршрут для получения моих значений

router.get("/dashboard", ensureAuthenticated, (req, res) => {
  House.aggregate([
    {
      $match: { members: req.user.id }
    },
    {
      $unwind: "$expensesHouse"
    },
    {
      $match: { "expensesHouse.status": "Public" }
    }
  ]).then(house => {
    console.log(house);
    res.render("houses/dashboard", {
      house: house
    });
  });
});

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

<tbody>
                            {{#each house}}
                            <tr>
                                <td></td>
                                <td>{{name}}</td>
                                <td>{{expensesHouse.expenseType}}</td>
                                <td>{{expensesHouse.price}}€</td>
                                <td>{{VALUE.DIVIDED}}</td>


                                <td>{{formatDate date 'MMMM Do YYYY'}}</td>
                                <td>
                                    <a href="/houses/showExpense/{{expensesHouse.id}}" id="detailsExpense"
                                        class="btn btn-outline-light mb-3"><i class="fas fa-eye mr-2"></i>Details
                                    </a>
                                <td>
                                    <a href="/houses/editExpense/{{expensesHouse.id}}" id="editExpense"
                                        class="btn btn-outline-light mb-3"><i class="fas fa-edit mr-2"></i>Edit
                                </td>
                            </tr>
                            {{else}}
                            <p>No expenses</p>
                            {{/each}}
                        </tbody>

MongoDB Document:

  name: {
    type: String,
    required: true
  },
  description: {
    type: String,
    required: true
  },
  address: {
    type: String,
    required: false
  },
  userType: {
    type: String,
    required: true
  },
  user: {
    type: String,
    required: true
  },
  userID: {
    type: String,
    required: true
  },
  members: [
    {
      type: String
    }
  ],
  expensesHouse: [
    {
      expenseType: {
        type: String
      },
      description: {
        type: String,
        required: true
      },
      price: {
        type: Number,
        require: true
      },
      status: {
        type: String,
        default: "public"
      },
      payAt: {
        type: Date
      },
      userID: {
        type: String,
        require: false
      },
      date: {
        type: Date,
        default: Date.now
      }
    }
  ],
  date: {
    type: Date,
    default: Date.now
  }
});

Любая помощь очень ценится! !

1 Ответ

2 голосов
/ 28 января 2020

Вы можете попробовать этот запрос:

House.aggregate([
    { $match: { members: 'someObjectIDInString' } },
    {
        $addFields: {
            expensesHouse: { // expensesHouse array will be replaced by objects resulted by map operator
                $map:
                {
                    /** $filter only retains objects in array which satisfy condition */
                    input: { $filter: { input: '$expensesHouse', as: 'each', cond: { $eq: ['$$each.status', 'Public'] } } },
                    as: "each",
                    /** will add a new field dividedValue to existing object */
                    in: { $mergeObjects: ['$$each', { dividedValue: { $divide: ["$$each.price", { $size: '$members' }] } }] }
                }
            }
        }
    }])

Сбор данных:

/* 1 */
{
    "_id" : ObjectId("5e2f6045d02e05b694913e10"),
    "members" : [ 
        "someObjectIDInString", 
        "someObjectIDInString2"
    ],
    "expensesHouse" : [ 
        {
            "status" : "Public",
            "price" : 60
        }, 
        {
            "status" : "Private",
            "price" : 40
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("5e2f6057d02e05b694913fb4"),
    "members" : [ 
        "someObjectIDInString", 
        "someObjectIDInString2", 
        "someObjectIDInString2"
    ],
    "expensesHouse" : [ 
        {
            "status" : "Public",
            "price" : 120
        }, 
        {
            "status" : "Public",
            "price" : 200
        }
    ]
}

Результат:

/* 1 */
{
    "_id" : ObjectId("5e2f6045d02e05b694913e10"),
    "members" : [ 
        "someObjectIDInString", 
        "someObjectIDInString2"
    ],
    "expensesHouse" : [ 
        {
            "status" : "Public",
            "price" : 60,
            "dividedValue" : 30.0
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("5e2f6057d02e05b694913fb4"),
    "members" : [ 
        "someObjectIDInString", 
        "someObjectIDInString2", 
        "someObjectIDInString2"
    ],
    "expensesHouse" : [ 
        {
            "status" : "Public",
            "price" : 120,
            "dividedValue" : 40.0
        }, 
        {
            "status" : "Public",
            "price" : 200,
            "dividedValue" : 66.6666666666667
        }
    ]
}
...