Оценка документа по массиву агрегации - PullRequest
0 голосов
/ 13 декабря 2018

Я хочу оценить документ в mongodb на основе элементов в документе.
Вот пример документа:

{
  _id: 5c1257cd37567213449066ce,
  elements: [
   {element: 'abc'},
   {element: 'def'},
   {element: 'ghi'},
  ]
}

, а следующий массив имеет оценку +5:

var plus = ['abc'];

и следующий массив имеет оценку -1;

var minus = ['def', 'ghi']

, и я хочу получить этот вывод

{
  _id: 5c1257cd37567213449066ce,
  score: 3
}

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Вы можете использовать ниже aggregation

db.collection.aggregate([
  { "$project": {
    "plus": {
      "$map": {
        "input": "$elements",
        "as": "s",
        "in": {
          "elements": "$$s.elements",
          "score": { "$cond": [{ "$in": ["$$s.element", ["abc"]] }, 5, 0] }
        }
      }
    },
    "minus": {
      "$map": {
        "input": "$elements",
        "as": "s",
        "in": {
          "elements": "$$s.elements",
          "score": { "$cond": [{ "$in": ["$$s.element", ["def", "ghi"]] }, 1, 0] }
        }
      }
    }
  }},
  { "$project": {
    "score": { "$subtract": [{ "$sum": "$plus.score" }, { "$sum": "$minus.score" }] }
  }}
])

Если вы хотите сделать с одной $project ступенью

db.collection.aggregate([
  { "$project": {
    "score": {
      "$subtract": [
        { "$sum": {
          "$map": {
            "input": "$elements",
            "in": { "$cond": [{ "$in": ["$$this.element", ["abc"]] }, 5, 0] }
          }
        }},
        { "$sum": {
          "$map": {
            "input": "$elements",
            "in": { "$cond": [{ "$in": ["$$this.element", ["def", "ghi"]] }, 1, 0] }
          }
        }}
      ]
    }
  }}
])
0 голосов
/ 13 декабря 2018

Вы можете просто перебирать свои элементы и суммировать отдельные значения.

  • Я использовал reduce здесь для итерации.
  • {element} для уничтожения элемента массиватолько его element значение.
  • .includes(), чтобы проверить, содержат ли массивы элемент.

const o = {
  _id: '5c1257cd37567213449066ce',
  elements: [{
      element: 'abc'
    },
    {
      element: 'def'
    },
    {
      element: 'ghi'
    },
  ]
};

const plus = ['abc'];

const minus = ['def', 'ghi']

function score(arr) {
  return arr.reduce((s, {
    element
  }) => {
    if (plus.includes(element)) return s + 5;
    if (minus.includes(element)) return s - 1;
    return s;
  }, 0);
}

o.score = score(o.elements);
console.log(o);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...