RavenDb:查找Actor X没有参与的电影

时间:2013-03-23 16:38:57

标签: ravendb

我是RavenDb的新手,我遇到了以下问题,这在SQL数据库中很容易解决,但在RavenDb中似乎并不那么容易(似乎)。

鉴于我的课程:

//document collection
public class Movie
{
    public string Id { get; set; }
    public string Title { get; set; }
    public List<MovieActor> Actors { get; set; }
}

public class MovieActor
{
    public string ActorId { get; set; }
    public string CharacterName { get; set; }
    public DateTime FirstAppearance { get; set; }
}

//document collection
public class Actor
{
    public string Id { get; set; }
    public string Name { get; set; }
}

使用以下地图索引查找Leonardo DiCaprio所扮演的每部电影都非常简单有效:

public class Movies_ByActor : AbstractIndexCreationTask<Movie>
{

    public Movies_ByActor()
    {
        Map = movies => from movie in movies
                        from actor in movie.Actors
                        select new
                        {
                            MovieId = movie.Id,
                            ActorId = actor.ActorId
                        };
    }
}

但这不是我想达到的目标,我想要相反......找到莱昂纳多迪卡普里奥没有表演的所有电影。

我也尝试了以下查询:

 var leonardoActorId = "actor/1";
 var movies = from movie in RavenSession.Query<Movie>()
              where !movie.Actors.Any(a => a.ActorId.Equals(leonardoActorId))
              select movie;

但这只会给我一个例外:

System.InvalidOperationException: Cannot process negated Any(), see RavenDB-732 http://issues.hibernatingrhinos.com/issue/RavenDB-732

任何人都知道如何在RavenDb中以正确的方式实现这一目标?

1 个答案:

答案 0 :(得分:3)

使用我博客文章中描述的方法:

http://www.philliphaydon.com/2012/01/18/ravendb-searching-across-multiple-properties/

您可以使用ActorIds数组创建索引:

public class Movies_ByActor : AbstractIndexCreationTask<Movie>
{
    public Movies_ByActor()
    {
        Map = movies => from s in movies
                        select new
                        {
                            Actors = s.Actors.Select(x => x.ActorId)
                        };
    }

    public class ActorsInMovie
    {
        public object[] Actors { get; set; }
    }
}

然后你可以搜索电影中不包含你想要的演员的地方:

var result = session.Query<Movies_ByActor.ActorsInMovie, Movies_ByActor>()
                    .Where(x => x.Actors != (object)"actors/1")
                    .As<Movie>();

由于我们要查询的对象与结果不同,我们需要指定As<T>来告诉RavenDB实际返回的对象类型是什么。

工作样本:http://pastie.org/7092908