3

I'm having trouble querying RavenDB with even the simplest of queries, probably I'm doing something wrong, but after a few hours I just can't see it anymore. I've googled almost anything I can think of..

I have these entities:

    public class User
    {
    public string Id { get; set; }
    public string DisplayName { get; set; }
    public string RealName { get; set; }
    public string Email { get; set; }
    public string PictureUri { get; set; }
    public List<Comment> Comments { get; set; } 

    public List<Role> Roles { get; set; }
 }

public class NewsItem
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string Text { get; set; }
    public DateTime Created { get; set; }
    public string UserId { get; set; }
    public List<Tag> Tags { get; set; }
    public List<Comment> Comments { get; set; }
    public List<WebImage> Images { get; set; } 
 }

I want to query these so I get a list of newsItems, but with the user information alongside it. So I read the docs and tried the LoadDocument feature, the index:

public class NewsItemIndexWithComments : AbstractIndexCreationTask<NewsItem, NewsItemIndexWithComments.Result>
{

    public class Result
    {
        public string AuthorName { get; set; }
    }

    public NewsItemIndexWithComments()
    {
        Map = newsItems => from newsItem in newsItems
                           select new
                           {
                               AuthorName = LoadDocument<User>(newsItem.UserId).DisplayName
                           };
    }
}

Which I try to use like:

var result = _documentSession.Query<NewsItemIndexWithComments.Result, NewsItemIndexWithComments>().AsProjection<NewsItemIndexWithComments.Result>().ToList();

Now I get the number of documents in my list, but the AuthorName is always null. If I don't use the AsProjection method, I won't get any results. Can anyone show me a proper example on which I can experiment further?

Thanks.

_ edit:

That helped a lot, thanks :) Now for step two, I'm sorry if I'm being a bit newbish, but you'll have to start somewhere. In the newsitems there are comments, in these comments there is another reference to the userid. You can probably guess what I want to do: I want the user info for the comments with the comments as well.

new Index:

public class NewsItemIndexWithComments : AbstractIndexCreationTask<NewsItem, NewsItemIndexWithComments.Result>
{

    public class Result : NewsItem
    {
        public string AuthorName { get; set; }
        public string AuthorId { get; set; }

    }

    public NewsItemIndexWithComments()
    {
        Map = newsItems => from newsItem in newsItems
                           let user = LoadDocument<User>(newsItem.UserId)
                           select new
                           {
                               AuthorName = user.DisplayName,
                               AuthorId = user.Id,
                           };
        Store(x => x.AuthorName, FieldStorage.Yes);
        Store(x => x.AuthorId, FieldStorage.Yes);
    }
}

Comment class:

public class Comment
{
    public string Id { get; set; }
    public string Text { get; set; }
    public string UserId { get; set; }
    public string User { get; set; }
    public DateTime Created { get; set; }
}

How can I query the comments and expand the results for that? Or is it better to create a new index just for the comments and get the user info analog to the solution above?

4

2 回答 2

4

你快到了,你只需要存储你正在投影的字段。将此添加到索引构造函数中,在地图之后。

Store(x=> x.AuthorName, FieldStorage.Yes);

这是因为您希望它返回并可供AsProjection查找。如果您只想在 where 或 orderby 中使用作者姓名,则不需要它。

于 2013-03-05T23:51:27.163 回答
0

如果您只想在 AsProjection 中包含注释,您可以简单地索引整个对象。

请注意,为自定义对象编制索引意味着您无法使用.Where(). RavenDB 只能查询展平的结果(整数、小数、字符串、日期)。

例如,为了查询标题,您需要创建一个单独的 Propertypublic string Title { get; set; }并将其映射到Title = newsItem.Title.

public class NewsItemIndexWithComments : AbstractIndexCreationTask<NewsItem, NewsItemIndexWithComments.Result>
{
public class Result : NewsItem
{
    public string AuthorName { get; set; }
    public string AuthorId { get; set; }
    public List<Comment> Comments { get; set; }

}

public NewsItemIndexWithComments()
{
    Map = newsItems => from newsItem in newsItems
                       let user = LoadDocument<User>(newsItem.UserId)
                       select new
                       {
                           AuthorName = user.DisplayName,
                           AuthorId = user.Id,
                           Comments = newsItem.Comments.
                       };
    Store(x => x.AuthorName, FieldStorage.Yes);
    Store(x => x.AuthorId, FieldStorage.Yes);
    Store(x => x.Comments, FieldStorage.Yes);
}

}

于 2016-06-17T00:15:30.593 回答