【问题标题】:RavenDb: Find movies that Actor X is NOT acting inRavenDb:查找演员 X 未出演的电影
【发布时间】:2016-02-03 21:48:35
【问题描述】:

我是 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 中以正确的方式实现这一点吗?

【问题讨论】:

  • 并不是说我对莱诺阿多·迪卡普里奥有任何反对 =)

标签: ravendb


【解决方案1】:

在这里使用我的博文中描述的方法:

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&lt;T&gt;来告诉RavenDB实际返回的对象的类型是什么。

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

【讨论】:

  • 太棒了,谢谢 =) 这很好用,帮助我理解了很多。只是,我必须将查询的 .Where 部分更改为:x => !x.Actors.Contains((object)"actors/1"))
猜你喜欢
  • 1970-01-01
  • 2015-06-24
  • 2020-08-03
  • 2015-06-25
  • 1970-01-01
  • 2020-06-21
  • 2020-11-22
  • 2017-07-04
  • 1970-01-01
相关资源
最近更新 更多