3

我是 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; }
}

使用以下地图索引查找莱昂纳多·迪卡普里奥出演的每一部电影非常简单有效:

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 中以正确的方式实现这一目标?

4

1 回答 1

3

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

http://www.philliphaydon.com/2012/01/18/ravenb-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

于 2013-03-23T18:53:18.003 回答