场景:
我目前正在我们的网站中创建搜索功能。此功能是返回符合所有给定条件的相册。 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;
提前感谢您提供的任何帮助/指导。任何帮助或建议都会非常感激。
答案 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类型将文档添加回我的相册集合。沮丧的循环仍在继续。
所以使用我的例子,我的推荐是......
如果您想在代码中对相册使用/操作,请确保您的索引要么将文档作为相册带回来,要么让您的索引带回您希望减少的结果,但要确保您在查询中添加了As&lt;'dynamic'&gt;()或AsProjection&lt;'Sometype'&gt;()方法。这样可以防止结果更改文档clr-type。
确保没有任何你忘记的session.SaveChanges()被调用。
请务必检查索引以确保它们是最新的。
简而言之,不要犯同样的愚蠢错误。显然我的无知是无限的:)
再次感谢回复的丹尼尔斯。我很感激帮助。