根据两个值查找元素 [英] Find element based on two values

查看:41
本文介绍了根据两个值查找元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对测试集合进行简单的查找

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 是通过使用集合运算符

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" ]

使用 ["$directors._id"]进行比较rel ="nofollow noreferrer"> $setIsSubset 运算符,它接收两个数组,并且当第一个数组是第二个数组的子集时(包括第一个数组等于第二个数组时)返回true,否则返回false

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆