根据两个值查找元素 [英] Find element based on two values
问题描述
我正在尝试对测试集合进行简单的查找
I'm trying to do a simple find on my test collection
这是一个入门示例:
{
"_id": "movie:1",
"title": "Vertigo",
"year": 1958,
"genre": "drama",
"summary": "Scottie Ferguson, ancien inspecteur de police, est sujet au vertige depuis qu'il a vu mourir son collègue. Elster, son ami, le charge de surveiller sa femme, Madeleine, ayant des tendances suicidaires. Amoureux de la jeune femme Scottie ne remarque pas le piège qui se trame autour de lui et dont il va être la victime... ",
"country": "DE",
"director": {
"_id": "artist:3",
"last_name": "Hitchcock",
"first_name": "Alfred",
"birth_date": "1899"
},
"actors": [
{
"_id": "artist:15",
"first_name": "James",
"last_name": "Stewart",
"birth_date": "1908",
"role": "John Ferguson"
},
{
"_id": "artist:16",
"first_name": "Kim",
"last_name": "Novak",
"birth_date": "1925",
"role": "Madeleine Elster"
},
{
"_id": "artist:282",
"first_name": "Arthur",
"last_name": "Pierre",
"birth_date": null,
"role": null
}
]
}
我想找到导演兼演员的电影.是否可以通过简单的$ elemMatch来做到这一点:
I would like to find movies where a director is also an actor. Is it possible to do it with a simple $elemMatch like :
find({actors: {$elemMatch: {"_id": "this.director._id"} })
谢谢!
推荐答案
来自 $where
将遵循:
From the previously linked dupe (possible), a solution using $where
would follow:
db.collection.find({
"$where": function() {
self = this;
return this.actors.filter(function(actor) {
return self.director._id === actor._id;
}).length > 0
}
})
And the other suggested approach which uses the aggregation framework $redact
pipeline:
db.collection.aggregate([
{
"$redact": {
"$cond": [
{
"$setIsSubset": [
["$director._id"],
{
"$map": {
"input": "$actors",
"as": "el",
"in": "$$el._id"
}
}
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
在上面, $redact
是通过使用集合运算符 $map
.
In the above, the condition logic for $redact
is done through the use of set operators $setIsSubset
and $map
.
$map
运算符在对数组中的每个元素应用表达式之后,将从actors
数组中返回一个仅包含actor id的数组.例如,表达式
The $map
operator will return an array with just the actor id's from the actors
array after applying an expression to each element in the array. So for example, the expression
{
"$map": {
"input": "$actors",
"as": "el",
"in": "$$el._id"
}
}
如果应用于actor数组
if applied on the actors array
[
{
"_id" : "artist:3",
"first_name" : "James",
"last_name" : "Stewart",
"birth_date" : "1908",
"role" : "John Ferguson"
},
{
"_id" : "artist:16",
"first_name" : "Kim",
"last_name" : "Novak",
"birth_date" : "1925",
"role" : "Madeleine Elster"
},
{
"_id" : "artist:282",
"first_name" : "Arthur",
"last_name" : "Pierre",
"birth_date" : null,
"role" : null
}
]
将返回
[ "artist:3", "artist:16", "artist:282" ]
使用 $setIsSubset
This result is compared with a single element array ["$directors._id"]
using the $setIsSubset
operator which takes two arrays and returns true when the first array is a subset of the second, including when the first array equals the second array, and false otherwise.
例如,
{
"$setIsSubset": [
[ "artist:12" ],
[ "artist:3", "artist:16", "artist:282" ]
]
} // false
{
$setIsSubset: [
[ "artist:282" ],
[ "artist:3", "artist:16", "artist:282" ]
]
} // true
操作员的布尔结果然后用作 $redact
管道.
The boolean result from the operator is then used as the basis for the $redact
pipeline.
关于性能的说明仍然有效: $where
是一个不错的技巧,但应尽可能避免.
The explanations for performance still hold: $where
is a good hack when necessary, but it should be avoided whenever possible.
这篇关于根据两个值查找元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!