MongoDBでランキング/検索数を求めるクエリの書き方
MongoDBでランキング/検索数を求めるクエリの書き方
MongoDBでランキングや検索数(検索キーワードとの一致率)を求めたい場合は、aggregate()メソッドを使います。この記事では、配列フィールドと検索語リストの一致率をもとにスコアを計算し、関連性の高い順に並べ替える方法を解説します。
1. コレクションの作成
まず、insertOne()メソッドを使ってサンプルドキュメントを登録し、コレクションを作成しましょう。
> db.demo120.insertOne(
... {
... 'Name': 'Chris',
... 'Subjects': [ 'MySQL', 'MongoDB', 'Java', 'Python' ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e2f11aed8f64a552dae6365")
}
> db.demo120.insertOne(
... {
... 'Name': 'Bob',
... 'Subjects': [ 'C', 'MongoDB' ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e2f11afd8f64a552dae6366")
}
2. 登録済みドキュメントの確認
find()メソッドを使うと、コレクション内のすべてのドキュメントを表示できます。
> db.demo120.find();
実行すると、次のような出力が得られます。
{ "_id" : ObjectId("5e2f11aed8f64a552dae6365"), "Name" : "Chris", "Subjects" : [ "MySQL", "MongoDB", "Java", "Python" ] }
{ "_id" : ObjectId("5e2f11afd8f64a552dae6366"), "Name" : "Bob", "Subjects" : [ "C", "MongoDB" ] }
3. ランキング/検索数を計算する集計クエリ
続いて、ランキング/検索数を求める本体のクエリです。ここでは「MySQL」「Java」「MongoDB」を検索語として設定し、各ドキュメントのSubjects配列にどれだけ含まれているかをスコア化しています。
- $match: 検索語のいずれかがSubjectsに含まれるドキュメントだけを抽出します。
- $addFields: 検索語とSubjectsの共通要素数($setIntersection+$size)を、Subjectsの総数で割った値($divide)を「RankSearch」フィールドとして追加します。
- $sort: RankSearchの降順(-1)に結果を並べ替えます。
> var s = ['MySQL', 'Java', 'MongoDB'];
> db.demo120.aggregate([
... { "$match": { "Subjects": { "$in": s } } },
... {
... "$addFields": {
... "RankSearch": {
... "$divide": [
... { "$size": { "$setIntersection": ["$Subjects", s] } },
... { "$size": "$Subjects" }
... ]
... }
... }
... },
... { "$sort": { "RankSearch": -1 } }
... ])
実行すると、次のような出力が得られます。
{ "_id" : ObjectId("5e2f11aed8f64a552dae6365"), "Name" : "Chris", "Subjects" : [ "MySQL", "MongoDB", "Java", "Python" ], "RankSearch" : 0.75 }
{ "_id" : ObjectId("5e2f11afd8f64a552dae6366"), "Name" : "Bob", "Subjects" : [ "C", "MongoDB" ], "RankSearch" : 0.5 }
結果の読み方
Chrisは4科目中3科目(MySQL・MongoDB・Java)が検索語と一致しているため、RankSearchは0.75(75%)です。一方、Bobは2科目中1科目(MongoDB)のみ一致しているので0.5(50%)となります。このように一致率をスコア化することで、検索条件との関連性が高いドキュメントほど上位に表示されるランキング機能を、aggregate()だけで簡単に実現できます。
-
MongoDBでフィールド値に含まれる「@email」のような文字列を検索する方法
MongoDBのfind()メソッドを使えば、正規表現(Regex)を活用して、フィールド値の中から特定の文字列を柔軟に検索できます。本記事では、「@email」という文字列を含むドキュメントを検索する方法を、実際のコード例とともに解説します。1. 検索用コレクションの作成まずは、メールアドレスを格納したドキュメントを持つコレクションを作成しましょう。> db.demo727.insertOne({UserId:John@email.com}); { acknowledged : true, insertedId : ObjectId(5eab375f4341781127
-
MongoDBの$regex演算子で大文字と小文字を区別しない検索を行う方法(iオプション)
MongoDBで大文字と小文字を区別せずに文字列検索を行いたい場合は、$regex演算子に「i」(case insensitive:大文字と小文字を区別しない)オプションを指定します。この記事では、実際にコレクションを作成し、「mongodb」という文字列を表記の違いにかかわらずすべて取得する方法を、サンプルコード付きで解説します。ドキュメントを含むコレクションの作成まず、insertOne()メソッドを使って、異なる表記(MySQL、MongoDB、mongodb、MONGODB)のドキュメントを持つコレクションを作成しましょう。> db.demo759.insertOne({Subj