次のようなドキュメントがあるとします。
{
tags: ['a', 'b']
}
タグのみを持つすべてのドキュメントを検索したいa
。私の現在のクエリ基準は次のとおりです。
{
tags: {
$size: 1,
$in: ['a']
}
}
equal
演算子を使用してクエリを実行する方法はありますか?
次のようなドキュメントがあるとします。
{
tags: ['a', 'b']
}
タグのみを持つすべてのドキュメントを検索したいa
。私の現在のクエリ基準は次のとおりです。
{
tags: {
$size: 1,
$in: ['a']
}
}
equal
演算子を使用してクエリを実行する方法はありますか?
配列のサイズをtags
別の属性として保存し、配列の変更時に更新しますtags
。
// Document
{
tags : ['a'],
tags_size : 1
}
// Criteria
{ tags_size : 1, tags : 'a' }
$size
オペレーターはインデックスを使用できないことに注意してください。
配列フィールドに対するクエリは暗黙的に配列値をチェックしますが、配列全体を照合することもできます。tags
次の例を考えてみましょう。この例では、フィールドに文字列と文字列の配列が混在しています。
> db.foo.find()
{ "_id" : ObjectId("502943541f5b0d2bca9663a8"), "tags" : [ "a" ] }
{ "_id" : ObjectId("502943581f5b0d2bca9663a9"), "tags" : [ "a", "b" ] }
{ "_id" : ObjectId("5029435e1f5b0d2bca9663aa"), "tags" : [ [ "a" ] ] }
{ "_id" : ObjectId("502943641f5b0d2bca9663ab"), "tags" : [ [ "a" ], "b" ] }
{ "_id" : ObjectId("5029436c1f5b0d2bca9663ac"), "tags" : [ [ "a" ], [ "b" ] ] }
{ "_id" : ObjectId("502943a31f5b0d2bca9663ad"), "tags" : [ "a", [ "b" ] ] }
"a"
inのクエリは、単独または部分的tags
に含まれるすべての配列に一致します。"a"
> db.foo.find({tags: "a"})
{ "_id" : ObjectId("502943541f5b0d2bca9663a8"), "tags" : [ "a" ] }
{ "_id" : ObjectId("502943581f5b0d2bca9663a9"), "tags" : [ "a", "b" ] }
{ "_id" : ObjectId("502943a31f5b0d2bca9663ad"), "tags" : [ "a", [ "b" ] ] }
表示されていませんが、tags
単純なフィールド"a"
(配列ではなく文字列値)があれば、それも確実に一致します。
["a"]
inをクエリすると、そのフィールドにのみ含まれているドキュメントと、値を含むすべての配列(つまり、ネストされた配列)tags
が一致します。"a"
tags
tags
["a"]
> db.foo.find({tags: ["a"]})
{ "_id" : ObjectId("502943541f5b0d2bca9663a8"), "tags" : [ "a" ] }
{ "_id" : ObjectId("5029435e1f5b0d2bca9663aa"), "tags" : [ [ "a" ] ] }
{ "_id" : ObjectId("502943641f5b0d2bca9663ab"), "tags" : [ [ "a" ], "b" ] }
{ "_id" : ObjectId("5029436c1f5b0d2bca9663ac"), "tags" : [ [ "a" ], [ "b" ] ] }
スキーマが文字列のみを配列に格納すると安全に想定できる場合はtags
、配列サイズを別のフィールドに格納してクエリ条件に追加するよりも、このクエリの方が望ましい場合があります(Mattが述べたように実行可能なソリューションでもあります)。