2
votes

Firstly, i am sorry for my english and i will be very happy if i can tell my problem very simply.

I spend so much time to solve multimap index and live projection problem. I read too much on stackoverflow, google, ayende blog etc... However couldn't solve my problem.

What i want: I have an app and want a twitter like search which is the twitter search box searches from multiple sources, such as from twit content, user names and hashtags. While i get result, i want to apply transform on results and shape index result into FullSearchResult model. Also i want to find that where the result is found. In the post, in user or in tag?

The problem : i have 3 type of docs (Post, User, Tag) and multimap index. When i create my multimap index with TransformResults i get all my results with null values. (I query my docs with multimap index by full text search).

My Docs

public class Post
{
    public string Id { get; set; }

    public long SqlDbId { get; set; }

    public string Title { get; set; }

    public string Content { get; set; }

    public string ContentAsHtml { get; set; }

    public Status Status { get; set; }

    public DenormalizedUser User { get; set; }

    public DenormalizedTagCollection Tags { get; set; }
}

public class User
{
    public string Id { get; set; }

    public string Name { get; set; }

    public string Surname { get; set; }

    public string Email { get; set; }

    public string MobileNumber { get; set; }
}

public class Tag
{
    public string Id { get; set; }

    public long SqlDbId { get; set; }

    public string TagName { get; set; }

    public DenormalizedUser TagInserterDenormalizedUser { get; set; }

    public bool IsSystemTag { get; set; }

    public Status Status { get; set; }
}

public class FullSearchIndex : AbstractMultiMapIndexCreationTask<FullSearchResult>
{
    public FullSearchIndex()
    {
        AddMap<Post>(posts => from post in posts
                              let tags = post.Tags
                              where post.Status == Status.Active
                              select new
                              {
                                  UserId = post.User != null ? post.User.Id.ToString() : (string)null,
                                  PostId = post.Id,
                                  TagIds = tags != null ? tags.Select(tag => tag.Id).ToArray() : new string[0],
                                  SearchQuery = new object[] 
                                  {                                      
                                      post.Title,
                                      post.Content,
                                      post.Tags != null ? tags.Select(x => x.TagName).ToArray() : new string[0]
                                  },
                                  Source = SearchResultSource.ResultIsFromPost
                              });

        AddMap<User>(users => from user in users
                              select new
                              {
                                  UserId = user.Id,
                                  PostId = (string)null,
                                  TagIds = new string[0],
                                  SearchQuery = new object[] 
                                  {                                      
                                      user.Name,
                                      user.Surname
                                  },
                                  Source = SearchResultSource.ResultIsFromUser
                              });

        AddMap<Tag>(tags => from tag in tags
                            where tag.Status == Status.Active
                            select new
                            {
                                UserId = (string)null,
                                PostId = (string)null,
                                TagIds = new string[] { tag.Id },
                                SearchQuery = new object[] 
                                {
                                    tag.TagName
                                },
                                Source = SearchResultSource.ResultIsFromTag
                            });

        Index(searchResult => searchResult.SearchQuery, FieldIndexing.Analyzed);

        TransformResults = (clientSideDatabase, results) =>
                                from result in results
                                let post = clientSideDatabase.Load<Post>(result.PostId)
                                let tags = clientSideDatabase.Load<Tag>(result.TagIds)
                                let user = clientSideDatabase.Load<User>(result.UserId)
                                select new
                                {
                                    PostId = post != null ? post.Id : (string)null,
                                    PostTitle = post != null ? post.Title : (string)null,
                                    PostContent = post != null ? post.Content : (string)null,
                                    PostTags = tags != null ? tags.Select(x => x.TagName).ToArray() : (string[])null,

                                    UserId = user != null ? user.Id : (string)null,
                                    UserName = user != null ? user.Name : (string)null,
                                    UserSurname = user != null ? user.Surname : (string)null,
                                    UserEmail = user != null ? user.Email : (string)null,
                                    UserMobileNumber = user != null ? user.MobileNumber : (string)null
                                };
    }
}

When i query using multimap index and lucene search i have 4 results. However, all values are null

query = "Tag50";
session.Query<FullSearchResult, FullSearchIndex>()
                        .Search(resultItem => resultItem.SearchQuery, query)
                        .As<FullSearchResultViewModel>()
                        .ToList();
1
Also, i see my index results projected as i want (FullSearchResultViewModel) in ravend studio with having values all nullnkaya

1 Answers

0
votes

Nkaya, You assumed that the input of the TransformResults is the output of the Maps, but that isn't the case. The input to TransformResults are the actual documents. The output of the maps is used to generate the index for searching ,not to shape how the input to the transform results looks like.