JavaScriptでデータベースから取得したデータを操作する場合、SQLを書くのは面倒です。そこで、JavaScriptのライブラリであるlodashを使用することで、データの操作が簡単になります。本記事では、lodashを使って実際にDBから取得したデータを操作する方法について解説します。
lodashはJavaScriptの汎用的なライブラリで、配列やオブジェクトを操作するための多くの関数を提供しています。データベースから取得したデータを操作する場合にも、lodashの関数を使うことができます。
たとえば、lodashのgroupBy()
関数を使うと、オブジェクト配列を指定したプロパティでグループ化することができます。また、orderBy()
関数を使うと、オブジェクト配列を指定したプロパティでソートすることができます。他にも、filter()
関数、find()
関数、map()
関数、reduce()
関数などがあります。これらの関数を組み合わせることで、SQLクエリに相当する操作をJavaScriptで実現することができます。
データベースから取得したデータを操作する場合は、取得したデータがオブジェクト配列であることを前提としています。また、lodashはJavaScriptのライブラリであるため、ブラウザやNode.js上で動作します。
使用方法
lodashでは、一般的に _
(アンダースコア) が変数名として使われます。これは、lodashのCDNから読み込む場合、 _
がlodashオブジェクトを表すためです。例えば、_.map()
は、lodashオブジェクトから提供される map()
関数を呼び出しています。
また、lodashを使う場合、以下のようにimportして使うこともできます。
import _ from 'lodash';
このように、lodashの関数をimportすることで、_.
を付けずに関数を呼び出すことができます。例えば、_.map()
を使う場合は、以下のように書き換えることができます。
import { map } from 'lodash';
const result = map(array, (item) => { ... });
ただし、この場合、必要な関数を1つずつimportする必要があるため、lodashの多くの関数を使う場合は、 import _ from 'lodash';
の方が便利です。
実例
group by, count
実際にデータベースから取得したデータを操作する場合を考えてみましょう。例えば、顧客情報が入ったテーブルを取得して、顧客の名前でグループ化し、各グループの顧客数を表示するといった処理を行いたいとします。
以下のようなSQLクエリを書くことができますが、結構複雑で覚えるのは大変です。
SELECT name, COUNT(*) FROM customers GROUP BY name;
そこで、lodashのgroupBy()
関数とmap()
関数を使って同じ処理を行ってみましょう。まず、テーブルから取得したデータを配列で表現します。
const customers = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Alice' },
{ id: 4, name: 'Charlie' },
{ id: 5, name: 'Alice' }
];
この配列をgroupBy()
関数で名前でグループ化します。次に、map()
関数で各グループの要素数を求めます。
const groupedCustomers = _.groupBy(customers, 'name');
const customerCounts = _.map(groupedCustomers, (group) => {
return {
name: group[0].name,
count: group.length
};
});
groupBy()
関数でグループ化した結果、以下のようなオブジェクトが得られます。
{
'Alice': [
{ id: 1, name: 'Alice' },
{ id: 3, name: 'Alice' },
{ id: 5, name: 'Alice' }
],
'Bob': [
{ id: 2, name: 'Bob' }
],
'Charlie': [
{ id: 4, name: 'Charlie' }
]
}
このオブジェクトをmap()
関数で要素数を求めることで、以下のような配列が得られます。
[
{ name: 'Alice', count: 3 },
{ name: 'Bob', count: 1 },
{ name: 'Charlie', count: 1 }
]
このように、lodashを使うことで、SQLクエリを書かずに顧客の名前でグループ化し、各グループの顧客数を表示するといった処理が書けました。
order by
続いて、orderBy()
関数を使って、要素を指定したプロパティでソートする方法を紹介します。例えば、顧客情報が入ったテーブルを取得して、注文数が多い順にソートし、顧客名と注文数を表示する処理を行いたいとします。
以下のようなSQLクエリを書くことができますが、ORDER BY句が複雑で、SQLの知識が必要です。
SELECT name, COUNT(*) as order_count
FROM customers
LEFT JOIN orders ON customers.id = orders.customer_id
GROUP BY name
ORDER BY order_count DESC;
そこで、lodashのorderBy()
関数を使って同じ処理を行ってみましょう。まず、テーブルから取得したデータを配列で表現します。
const customers = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Alice' },
{ id: 4, name: 'Charlie' },
{ id: 5, name: 'Alice' }
];
const orders = [
{ id: 1, customer_id: 1 },
{ id: 2, customer_id: 1 },
{ id: 3, customer_id: 2 },
{ id: 4, customer_id: 3 },
{ id: 5, customer_id: 3 },
{ id: 6, customer_id: 3 }
];
この配列をgroupBy()
関数とmap()
関数を組み合わせて顧客名と注文数を求めます。
const groupedOrders = _.groupBy(orders, 'customer_id');
const customerOrders = _.map(groupedOrders, (orders, customerId) => {
const customer = _.find(customers, { id: parseInt(customerId) });
return {
name: customer.name,
orderCount: orders.length
};
});
groupBy()
関数でグループ化した結果、以下のようなオブジェクトが得られます。
{
'1': [
{ id: 1, customer_id: 1 },
{ id: 2, customer_id: 1 }
],
'2': [
{ id: 3, customer_id: 2 }
],
'3': [
{ id: 4, customer_id: 3 },
{ id: 5, customer_id: 3 },
{ id: 6, customer_id: 3 }
]
}
このオブジェクトをmap()
関数で注文数を求め、orderBy()
関数で注文数でソートすることで、以下のような配列が得られます。
[
{ name: 'Charlie', orderCount: 3 },
{ name: 'Alice', orderCount: 2 },
{ name: 'Bob', orderCount: 1 }
]
where
続いて、filter()
関数を使って、オブジェクト配列から条件に合う要素を取り出す方法を紹介します。例えば、注文情報が入ったテーブルから、特定の顧客の注文情報だけを取得する処理を行いたいとします。
以下のようなSQLクエリを書くことができますが、WHERE句が複雑で、SQLの知識が必要です。
SELECT * FROM orders WHERE customer_id = 1;
そこで、lodashのfilter()
関数を使って同じ処理を行ってみましょう。まず、テーブルから取得したデータを配列で表現します。
const orders = [
{ id: 1, customer_id: 1, product: 'A' },
{ id: 2, customer_id: 2, product: 'B' },
{ id: 3, customer_id: 1, product: 'C' },
{ id: 4, customer_id: 3, product: 'D' },
{ id: 5, customer_id: 1, product: 'E' }
];
この配列をfilter()
関数でcustomer_idが1の注文情報だけを取得します。
const customerId = 1;
const customerOrders = _.filter(orders, { customer_id: customerId });
まとめ
以上のように、lodashを使うことで、データベースから取得したデータを簡単に操作することができます。開発者は、SQLクエリを書く手間を省いて、より簡潔かつ効率的なコードを書くことができます。また、lodashには、先に紹介したgroupBy()
関数、orderBy()
関数、map()
関数、reduce()
関数など、他にも多くの便利な関数が用意されているため、開発に役立てることができます。