RavenDB索引涵盖单个以及文档中的对象列表

时间:2012-03-19 13:48:42

标签: ravendb

场景:

我目前正在我们的网站中创建搜索功能。此功能是返回符合所有给定条件的相册。 IE浏览器。专辑标题,作曲家等我对Raven中的全文搜索有一点了解,我可能不得不最终尝试使用它。

我希望尽管我可以使用单个索引而只是查询索引。 (不幸的是,我现在不够了解为什么我应该/不应该这样做而不是全文索引,所以我愿意接受建议:))

值得注意的事情......相册是我们目前在Raven中唯一的一个集合,因为它是通过从备用系统导入的数据提供给raven的。它可以被认为是与专辑相关的所有内容的非规范化视图。

以下是我们专辑的一个例子:

public class Album
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public List<string> Composers { get; set; }
    public List<string> MusicCategories { get; set; }
    public List<string> PerformingGroups { get; set; }
    public List<string> Instruments { get; set; }            
}

以下是我尝试创建的索引。标题搜索有效但我在搜索集合中的项目时没有返回任何结果。我只能想象它与我不做任何类型的地图/缩小和投影这一事实有关。但这只是我的一个猜测。

ravenSessionManager.DocumentStore.DatabaseCommands
            .PutIndex("AlbumsBySearchCriteria", new IndexDefinitionBuilder<Album>
            {
                Map = albums => from a in albums
                                select
                                    new
                                    {
                                        a.Title,
                                        a.Composers,
                                        a.MusicCategories,
                                        a.Instruments
                                    },
                Indexes =
                                                      {
                                                          {x => x.Title, FieldIndexing.Analyzed},
                                                          {x => x.Composers, FieldIndexing.Analyzed},FieldIndexing.Analyzed},
                                                          {x => x.MusicCategories, FieldIndexing.Analyzed},FieldIndexing.Analyzed},
                                                          {x => x.Instruments, FieldIndexing.Analyzed}

                                                      }
            });

最后下面是我的查询示例:

 var query = (from a in _documentSession.Query<Album>("AlbumsBySearchCriteria")
                         select a);

            if(!string.IsNullOrEmpty(criteria.Title))
                query = query.Where(a => a.Title.StartsWith(criteria.Title));
            if (!string.IsNullOrEmpty(criteria.Composer))
                query = query.Where(a => a.Composers.Any(c => c.StartsWith(criteria.Composer)));
return query;

提前感谢您提供的任何帮助/指导。任何帮助或建议都会非常感激。

1 个答案:

答案 0 :(得分:1)

好的,所以我已经找到了我所面临的问题,我想我会分享一些背景,让其他人看到我所犯的错误。首先,我要感谢Daniel的回答。他的解决方案确实并且将会正常工作。值得一提的是,我的原始解决方案也会起作用,只要你没有犯下我做过的愚蠢错误:)。

错误#1 :我的解决方案最初似乎因为我不知道的新ETL文件而失败,以及旧的错误索引。不幸的是,我要“在杂草丛中”注意到。

错误#2 :Daniels的例子并不完全是我需要的所以我不得不做一些调整,而在调整时我忘了把“As&lt;'dynamic'&gt;”我的查询就像丹尼尔的例子一样。

如果您希望将查询结果作为原始clr类型(文档保存为),您的索引不会返回相同的类型,那么添加它是很重要的“as&lt;'dynamic'&gt;()”或“AsProjection&lt;'SomeType'&gt;()”对您的查询。因为,当查询时,Raven会将文档的clr类型转换为您在索引中指定的clr类型。在我的情况下,究竟发生了什么。我希望按照类型相册对我的结果进行操作,但是从查询返回的文档正在从“Album”类型更改为“ReduceResult”,正如人们所期望的那样。我没想到的是,它会标记文档中已更改的更改,如果调用了SaveChanges(),它现在会将我的文档保存为新类型。这让我误以为3号。

错误#3 :我所做的一切都是在“工作单元”模式中,我忘记了在我的http请求结束时我调用了一个ravenSession.SaveChanges()。这就是我的命运:(。因为在错误2中提到的查询过程中我的类型被更改了,我现在发现自己在同一个集合中有不同clr类型的文档。

最终的结果是每次我对我的索引执行搜索并返回多个具有不同clr类型的文档时,我会得到一个无效的强制转换异常。为了使事情变得更糟,我抓住了所有异常,以便我可以适当地处理它们并将特定结果返回给调用客户端。因此我的SaveChanges()总是被触发,因此使用不同的clr类型将文档添加回我的相册集合。沮丧的循环仍在继续。

所以使用我的例子,我的推荐是......

  1. 如果您想在代码中对相册使用/操作,请确保您的索引要么将文档作为相册带回来,要么让您的索引带回您希望减少的结果,但要确保您在查询中添加了As&lt;'dynamic'&gt;()或AsProjection&lt;'Sometype'&gt;()方法。这样可以防止结果更改文档clr-type。

  2. 确保没有任何你忘记的session.SaveChanges()被调用。

  3. 请务必检查索引以确保它们是最新的。

  4. 简而言之,不要犯同样的愚蠢错误。显然我的无知是无限的:)

    再次感谢回复的丹尼尔斯。我很感激帮助。