我是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中以正确的方式实现这一目标?
答案 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实际返回的对象类型是什么。