Как получить все «Столбцы» из Parse платформы «Таблица», используя разные, как GROUP BY на SQL - PullRequest
0 голосов
/ 21 октября 2019

Я использую Parse с Postgres, и мне нужно извлечь несколько строк из таблицы.

Мне нужно сгруппировать по одному столбцу, как GROUP BY в SQL, но когда я используюdistinct или aggregate в моих запросах, оба просто возвращают столбец, который я использую в качестве параметра, а не все столбцы.

Пример

Моя таблица

Product | Category | Price
--------+----------+------
Apple   | Fruit    |     5
Orange  | Fruit    |     3
Rice    | Cereal   |     8
Grape   | Fruit    |     6

Затем я запускаю запрос:

query.distinct('Category').then(....

Что приводит к:

["Fruit", "Cereal"]

Но я хочу что-то вроде:

[
  {Product: Apple, Category: Fruit, Price:5},
  {Product: Rice, Category: Cereal, Price:8}
]

Как я уже сказал,точно так же как GROUP BY через SQL.

Это возможно?

В настоящее время я использую один запрос с .distinct() и результаты этого запроса в качестве параметра в .containedIn(), но я думаю, что это должен быть лучший способ сделать это ...

Ответы [ 2 ]

1 голос
/ 22 октября 2019

Вы можете использовать агрегат для достижения того, что вы ищете в одном запросе:

await Promise.all([
  new Parse.Object('MyTable').save({ Product: 'Apple', Category: 'Fruit', 'Price': 5 }),
  new Parse.Object('MyTable').save({ Product: 'Orange', Category: 'Fruit', 'Price': 3 }),
  new Parse.Object('MyTable').save({ Product: 'Rice', Category: 'Cereal', 'Price': 8 }),
  new Parse.Object('MyTable').save({ Product: 'Grape', Category: 'Fruit', 'Price': 6 }),
]);

const pipeline = [{
  group: {
    objectId: '$Category',
    first: { $first: "$$ROOT" },
  },
},
{
  project: {
    objectId: false,
    Product: "$first.Product",
    Category: "$first.Category",
    Price: "$first.Price",
  },
}];


const result = await new Parse.Query('MyTable')
  .aggregate(pipeline);

console.log(result);

, который выдает следующий результат:

[ { Product: 'Rice', Category: 'Cereal', Price: 8 },
  { Product: 'Grape', Category: 'Fruit', Price: 6 } ]

См .:

Если вы хотите указатьВ порядке, вы можете добавить этап сортировки в свой конвейер.

Если вы хотите понять, что происходит, удалите этап project, и вы увидите необработанный вывод этапа group.

0 голосов
/ 21 октября 2019

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

function groupBy(data, key) {
  return data.reduce((groups, item) => {
    if (groups[item[key]] === undefined) {
      groups[item[key]] = item; // Only store the first one that matches
    }
    return groups;
  }, {});
}

Существует три различных способа группировки.

  1. groupBy - Ваш желаемый результат
  2. groupByCount - Количество предметов, которые в каждой категории
  3. groupByAll - Все предметы, сгруппированные по их категории

let csvData = `
  Product,Category,Price
  Apple,Fruit,5
  Orange,Fruit,3
  Rice,Cereal,8
  Grape,Fruit,6
`;
let jsonData = csvToJson(csvData, true);

console.log(groupBy(jsonData, 'Category'));
console.log(groupByCount(jsonData, 'Category'));
console.log(groupByAll(jsonData, 'Category'));

function groupBy(data, key) {
  return data.reduce((groups, item) => {
    if (groups[item[key]] === undefined) {
      groups[item[key]] = item;
    }
    return groups;
  }, {});
}

function groupByCount(data, key) {
  return data.reduce((groups, item) => {
    groups[item[key]] = (groups[item[key]] || 0) + 1;
    return groups;
  }, {});
}

function groupByAll(data, key) {
  return data.reduce((groups, item) => {
    groups[item[key]] = (groups[item[key]] || []).concat(item);
    return groups;
  }, {});
}

function csvToJson(csv, headersIncl) {
  return (lines => {
    return (headersIncl ? lines.slice(1) : lines).map((line) => {
      return lines[0].reduce((obj, key, i) => {
        return Object.assign(obj, {
          [headersIncl ? key : i]: line[i]
        });
      }, {});
    });
  })(csv.trim().split('\n').map(line => line.trim().split(/\s*,\s*/g)));
}
.as-console-wrapper { top: 0; max-height: 100% !important; }
...