与此问题相关:RavenDB Get By List of IDs? 我所拥有的不起作用:
public class Entity
{
public int CategoryId; //Unique identifier for the category the price applies to.
public int Price; //Changes with time
public DateTime Timestamp; //DateTime.UtcNow
}
public class LastEntityIndex : AbstractIndexCreationTask<Entity, Entity>
{
public LastEntityIndex()
{
Map = prices => prices.Select(a => new { a.CategoryId, a.Price, a.Timestamp });
Reduce = prices => from price in prices
group price by price.CategoryId
into g
let a = g.OrderByDescending(a => a.Timestamp).FirstOrDefault()
select new
{
a.CategoryId,
a.Price,
a.Timestamp
};
}
}
public class LastEntity
{
public int CategoryId;
public DateTime Timestamp;
public Entity LastEntity;
}
public class LastReportIndex : AbstractIndexCreationTask<Entity, LastEntity>
{
public LastReportIndex()
{
Map = reports => reports.Select(a => new { a.CategoryId, a.Timestamp, LastEntity = a });
Reduce = reports => from report in reports
group report by report.CategoryId
into g
let a = g.OrderByDescending(a => a.Timestamp).FirstOrDefault()
select new
{
a.CategoryId,
a.Timestamp,
a.LastEntity
};
}
}
我想创建一个索引来获取每个类别的最新记录。但以上都没有奏效。任何帮助都非常感谢。远离sql这个新项目并评估Raven。到目前为止,它似乎非常强大并且可以满足我们的需求,但是从sql dbs转移范式很难。
非常感谢。
PS 使用它来检索记录:
public List<Entity> GetLastEntityForCategoryIds(List<int> categoryIds)
{
using (var session = _documentStore.OpenSession())
{
return session.Query<LastEntity, LastReportIndex>()
.Where(x => x.CategoryId.In(categoryIds))
.Select(a => a.LastEntity)
.ToList();
}
}
显然'LastEntityIndex'不是我长期使用的东西(它只是试试看是否有效),因为真正的实体有更多的字段只有3并且将它们全部复制并维护它非常努力
答案 0 :(得分:1)
您是正确的,您必须选择整个文档,而不是文档的部分。默认情况下,查询返回整个文档。
如果您只想返回文档的一部分,则必须使用projections或transformers,或者按照您的方式行事并完成所有操作并然后拿出你想要的零件。
然而,你做了很多我认为不必要的事情。例如,您在reduce中订购并获取单个项目。这不是一个很好的索引使用。您可能只需要一个简单的地图并按查询进行排序。
请参阅this GIST并阅读我的评论。其他一些内容也在评论中。
也为你欢呼!
答案 1 :(得分:0)
是的,我弄清楚发生了什么。 如果我这样做。选择Mapped / Reduced查询,返回默认值。 如果我这样做.ToList()。选择或Single()等我得到了正确的结果。
这是我设置的单元测试,用于演示我在说什么。
using Raven.Client.Indexes;
using Raven.Tests.Helpers;
using System;
using System.Linq;
using Xunit; //XUnit
//using Microsoft.VisualStudio.TestTools.UnitTesting; //MSTest
namespace RavenDBTest.Tests
{
//[TestClass] //MSTest
public class RavenIndexTest : RavenTestBase
{
//[TestMethod] //MSTest
[Fact] //XUnit
public void CanIndexAndQuery()
{
var timestamp = DateTime.Now;
var report1 = new Entity { CategoryId = 123, Price = 51, Timestamp = timestamp.AddSeconds(-20) };
var report2 = new Entity { CategoryId = 123, Price = 62, Timestamp = timestamp.AddSeconds(-10) };
var report3 = new Entity { CategoryId = 123, Price = 73, Timestamp = timestamp };
using (var store = NewDocumentStore())
{
new LatestEntity_Index().Execute(store);
using (var session = store.OpenSession())
{
session.Store(report1);
session.Store(report2);
session.Store(report3);
session.SaveChanges();
}
//WILL PASS
using (var session = store.OpenSession())
{
var result = session.Query<LastEntity, LatestEntity_Index>()
.Customize(customization => customization.WaitForNonStaleResultsAsOfNow())
.FirstOrDefault()
.LastReport;
AssertLatestResult(timestamp, result);
}
//WILL FAIL
using (var session = store.OpenSession())
{
var result = session.Query<LastEntity, LatestEntity_Index>()
.Customize(customization => customization.WaitForNonStaleResultsAsOfNow())
.Select(a => a.LastReport)
.FirstOrDefault();
AssertLatestResult(timestamp, result);
}
}
}
private static void AssertLatestResult(DateTime timestamp, Entity result)
{
//MSTest:
//Assert.AreEqual(123, result.CategoryId, "Category Does Not Match");
//Assert.AreEqual(73, result.Price, "Latest Price Does Not Match");
//Assert.AreEqual(timestamp, result.Timestamp, "Latest Timestamp Does Not Match");
//XUnit:
Assert.Equal(123, result.CategoryId);
Assert.Equal(73, result.Price);
Assert.Equal(timestamp, result.Timestamp);
}
}
public class Entity
{
public int CategoryId {get;set;} //Unique identifier for the category the price applies to.
public int Price {get;set;} //Changes with time
public DateTime Timestamp {get;set;} //DateTime.UtcNow
}
public class LastEntity
{
public int CategoryId { get; set; }
public DateTime Timestamp { get; set; }
public Entity LastReport { get; set; }
}
public class LatestEntity_Index : AbstractIndexCreationTask<Entity, LastEntity>
{
public LatestEntity_Index()
{
Map = reports => from report in reports
select new LastEntity
{
CategoryId = report.CategoryId,
Timestamp = report.Timestamp,
LastReport = report,
};
Reduce = reports => from report in reports
group report by report.CategoryId
into g
let last = g.OrderBy(a=>a.Timestamp).Last()
select new LastEntity
{
CategoryId = g.Key,
Timestamp = last.Timestamp,
LastReport = last.LastReport,
};
}
}
}
我希望这有助于某人。
@Matt Johnson,这些指数的效率/糟糕程度如何?表现明智吗?和太空明智吗? 顺便为你的帮助干杯。 :)