MongoDBで特定の文字数を超える文字列を検索する方法【$where演算子の使い方】
MongoDBで、特定の文字数より長い文字列を持つドキュメントを検索したい場合には、$where演算子を使用します。$where演算子ではJavaScriptの式を条件として指定できるため、フィールドの文字列長(length)を直接評価することが可能です。
$where演算子の基本構文
基本的な構文は以下の通りです。
db.yourCollectionName.find({$where:'this.yourStringFieldName.length > yourIntegerValue'}).pretty();サンプルコレクションの作成
それでは、実際の動作を確認するために、ドキュメントを含むコレクションを作成してみましょう。以下のクエリを実行して、コレクションにドキュメントを挿入します。
> db.stringFieldLengthDemo.insertOne({"UserId":1,"UserName":"Adam Smith"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c77bb4b2386c62d05142a78")
}
> db.stringFieldLengthDemo.insertOne({"UserId":2,"UserName":"Carol Taylor"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c77bb562386c62d05142a79")
}
> db.stringFieldLengthDemo.insertOne({"UserId":3,"UserName":"James Brown"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c77bb5b2386c62d05142a7a")
}
> db.stringFieldLengthDemo.insertOne({"UserId":4,"UserName":"John Smith"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c77bb662386c62d05142a7b")
}
> db.stringFieldLengthDemo.insertOne({"UserId":5,"UserName":"David Miller"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c77bb892386c62d05142a7c")
}
> db.stringFieldLengthDemo.insertOne({"UserId":6,"UserName":"John Williams"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c77bbb02386c62d05142a7d")
}
> db.stringFieldLengthDemo.insertOne({"UserId":7,"UserName":"Chris Evans"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c77bbd32386c62d05142a7e")
}登録済みドキュメントの確認
find()メソッドを使用すると、コレクション内のすべてのドキュメントを表示できます。クエリは以下の通りです。
> db.stringFieldLengthDemo.find().pretty();
実行結果は次のようになります。
{
"_id" : ObjectId("5c77bb4b2386c62d05142a78"),
"UserId" : 1,
"UserName" : "Adam Smith"
}
{
"_id" : ObjectId("5c77bb562386c62d05142a79"),
"UserId" : 2,
"UserName" : "Carol Taylor"
}
{
"_id" : ObjectId("5c77bb5b2386c62d05142a7a"),
"UserId" : 3,
"UserName" : "James Brown"
}
{
"_id" : ObjectId("5c77bb662386c62d05142a7b"),
"UserId" : 4,
"UserName" : "John Smith"
}
{
"_id" : ObjectId("5c77bb892386c62d05142a7c"),
"UserId" : 5,
"UserName" : "David Miller"
}
{
"_id" : ObjectId("5c77bbb02386c62d05142a7d"),
"UserId" : 6,
"UserName" : "John Williams"
}
{
"_id" : ObjectId("5c77bbd32386c62d05142a7e"),
"UserId" : 7,
"UserName" : "Chris Evans"
}特定の文字数を超える文字列を検索するクエリ
ここでは、例として「11文字より長い」UserNameを持つドキュメントをMongoDBで検索してみます。クエリは以下の通りです。
> db.stringFieldLengthDemo.find({$where:'this.UserName.length > 11'}).pretty();実行結果は次のようになります。
{
"_id" : ObjectId("5c77bb562386c62d05142a79"),
"UserId" : 2,
"UserName" : "Carol Taylor"
}
{
"_id" : ObjectId("5c77bb892386c62d05142a7c"),
"UserId" : 5,
"UserName" : "David Miller"
}
{
"_id" : ObjectId("5c77bbb02386c62d05142a7d"),
"UserId" : 6,
"UserName" : "John Williams"
}このように、11文字を超える「Carol Taylor」「David Miller」「John Williams」の3件だけが抽出されました。
補足:$exprと$strLenCPを使う代替手段
MongoDB 3.4以降では、$whereの代わりに$exprと$strLenCP演算子を組み合わせる方法が推奨されています。具体的には以下のように記述します。
> db.stringFieldLengthDemo.find({
$expr: { $gt: [ { $strLenCP: "$UserName" }, 11 ] }
}).pretty();$whereは各ドキュメントに対してJavaScriptを実行するため、インデックスを利用できず、大規模なコレクションではパフォーマンスが低下しやすいという注意点があります。一方、$exprと$strLenCPを使えば集計フレームワークの最適化の恩恵を受けられるため、本番環境ではこちらを選択するとよいでしょう。
-
Pythonでリスト内の「Kより大きい最小値」を取得する3つの方法
Pythonでデータ分析を行う際、リストから特定の条件を満たす要素を抽出したい場面は多くあります。本記事では、その中でも特に実用的なケースとして、「指定した値Kより大きい要素のうち、最も小さい値(=Kに最も近い大きい値)」を取得する方法を3つ紹介します。方法1:min関数とジェネレータ式を使うまず基本となるのが、リスト内包表記(ジェネレータ式)と min 関数を組み合わせる方法です。forループでリストの各要素を走査しながら、「値がKより大きい」という条件でフィルタリングし、条件を満たす要素の中から min 関数を使って最小値を取り出します。サンプルコード k) # 結果を表示 print(
-
Pythonでターゲット文字より大きい最小の文字を二分探索で見つける方法
ソート済みの小文字アルファベットのリスト letters と、ターゲットとなる文字 t が与えられたとき、リストの中から「t よりも大きい文字のうち最小のもの」を探す問題を考えてみましょう。このとき、文字は循環(ラップアラウンド)するとします。つまり、target = z で letters = [a, b] のような場合、z より大きい文字が存在しないため、先頭に戻って答えは a になります。例えば、入力が [c, f, j] で target が a の場合、a より大きい最小の文字は c なので、出力は c となります。解き方のアプローチ:二分探索リストがソート済みであるため、二分探索(