如何使 Raven DB Lucene 查询与结果转换器一起工作
How to make Raven DB Lucene query work with result transformer
我有一个 RavenDB Linq 查询,它使用一个正常工作的结果转换器,我正试图将其转换为 Lucene 语法,以便于创建动态查询。但是,我无法让 Lucene 查询正常工作,我正在寻找一些指导。
结果转换器:
public class CallRecordWithDisplayNameTransformer : AbstractTransformerCreationTask<CallRecord>
{
public CallRecordWithDisplayNameTransformer()
{
TransformResults = callRecords => from callRecord in callRecords
let displayNameRecord = LoadDocument<DisplayName>(callRecord.PhoneNumber)
let displayName = (displayNameRecord != null) ? displayNameRecord.Name : string.Empty
select new{
CallRecord = callRecord,
DisplayName = displayName
};
}
}
转换器创建的结果class:
public class CallRecordWithDisplayName
{
public CallRecord CallRecord { get; set; }
public string DisplayName { get; set; }
}
这是成功运行的 Linq 查询(当执行此查询时,返回了 25 个完全填充和转换的 'CallRecordWithDisplayName' 对象):
session.Query<CallRecord>()
.Customize(x => x.WaitForNonStaleResults(TimeSpan.FromSeconds(5)))
.OrderByDescending(c => c.CallDateTime)
.TransformWith<CallRecordWithDisplayNameTransformer, CallRecordWithDisplayName>()
.Skip(0)
.Take(25)
.ToList();
这是无法正常工作的 Lucene 查询。执行此查询时,它 returns 25 null 'CallRecord' 对象的实例,而不是转换器创建的 'CallRecordWithDisplayName' 对象。
session.Advanced.LuceneQuery<CallRecord>()
.OrderByDescending("CallDateTime")
.Skip(0)
.Take(25)
.SetResultTransformer(new CallRecordWithDisplayNameTransformer().TransformerName)
.ToList();
以下服务器日志显示了针对 Linq(请求 #584)和 Lucene(请求 #585)请求发送到服务器的查询:
Request # 584: GET - 7 ms - FiddleFlights - 200 - /indexes/dynamic/CallR
ecords?&pageSize=25&sort=-CallDateTime&resultsTransformer=CallRecordWithDisplayN
ameTransformer&operationHeadersHash=525986370
Query:
Time: 6 ms
Index: Auto/xz2MTg77IKTTb7MyHLD/4A==
Results: 25 returned out of 597 total.
Request # 585: GET - 7 ms - FiddleFlights - 200 - /indexes/dynamic/CallR
ecords?&pageSize=25&sort=-CallDateTime&resultsTransformer=CallRecordWithDisplayN
ameTransformer
Query:
Time: 5 ms
Index: Auto/xz2MTg77IKTTb7MyHLD/4A==
Results: 25 returned out of 597 total.
尝试创建 CallRecords 的静态索引并像这样调用它:
session.Advanced.LuceneQuery<CustomerNameViewModel, Customers_ByName>()
.OrderByDescending("Name")
.Skip(0)
.Take(25)
.SetResultTransformer(new CustomerNameTransformer().TransformerName)
.ToList();
编辑:或像这样使用自动索引:
session.Advanced.LuceneQuery<CustomerNameViewModel>("Auto/Customers/ByName")
在我的例子中,Customer 就是您的 CallRecord。
这在 RavenDB 3.0.3599 中对我有效,但是,如果您使用的是 3.0,则应使用 DocumentQuery<> 而不是 LuceneQuery,因为后者已过时(但它有效)。
但是,我不确定这是 "correct" 的方法,但我找不到另一种方法来定义与 .SetResultTransformer 一起使用的 Transformer 的 return 类型(...)
希望对您有所帮助!
编辑:这是我的转换器,用奇怪的 LoadDocument 构建只是为了测试。所以它没有任何 "real" 意义:
public class CustomerNameTransformer : AbstractTransformerCreationTask<Customer>
{
public CustomerNameTransformer()
{
TransformResults = results => from customer in results
let fixture = LoadDocument<Fixture>(customer.FixtureNumber)
select new CustomerNameViewModel
{
Id = customer.Id,
Name = customer.Name,
FixtureNumber = fixture.FixtureNumber,
Customer = customer
};
}
}
我有一个 RavenDB Linq 查询,它使用一个正常工作的结果转换器,我正试图将其转换为 Lucene 语法,以便于创建动态查询。但是,我无法让 Lucene 查询正常工作,我正在寻找一些指导。
结果转换器:
public class CallRecordWithDisplayNameTransformer : AbstractTransformerCreationTask<CallRecord>
{
public CallRecordWithDisplayNameTransformer()
{
TransformResults = callRecords => from callRecord in callRecords
let displayNameRecord = LoadDocument<DisplayName>(callRecord.PhoneNumber)
let displayName = (displayNameRecord != null) ? displayNameRecord.Name : string.Empty
select new{
CallRecord = callRecord,
DisplayName = displayName
};
}
}
转换器创建的结果class:
public class CallRecordWithDisplayName
{
public CallRecord CallRecord { get; set; }
public string DisplayName { get; set; }
}
这是成功运行的 Linq 查询(当执行此查询时,返回了 25 个完全填充和转换的 'CallRecordWithDisplayName' 对象):
session.Query<CallRecord>()
.Customize(x => x.WaitForNonStaleResults(TimeSpan.FromSeconds(5)))
.OrderByDescending(c => c.CallDateTime)
.TransformWith<CallRecordWithDisplayNameTransformer, CallRecordWithDisplayName>()
.Skip(0)
.Take(25)
.ToList();
这是无法正常工作的 Lucene 查询。执行此查询时,它 returns 25 null 'CallRecord' 对象的实例,而不是转换器创建的 'CallRecordWithDisplayName' 对象。
session.Advanced.LuceneQuery<CallRecord>()
.OrderByDescending("CallDateTime")
.Skip(0)
.Take(25)
.SetResultTransformer(new CallRecordWithDisplayNameTransformer().TransformerName)
.ToList();
以下服务器日志显示了针对 Linq(请求 #584)和 Lucene(请求 #585)请求发送到服务器的查询:
Request # 584: GET - 7 ms - FiddleFlights - 200 - /indexes/dynamic/CallR
ecords?&pageSize=25&sort=-CallDateTime&resultsTransformer=CallRecordWithDisplayN
ameTransformer&operationHeadersHash=525986370
Query:
Time: 6 ms
Index: Auto/xz2MTg77IKTTb7MyHLD/4A==
Results: 25 returned out of 597 total.
Request # 585: GET - 7 ms - FiddleFlights - 200 - /indexes/dynamic/CallR
ecords?&pageSize=25&sort=-CallDateTime&resultsTransformer=CallRecordWithDisplayN
ameTransformer
Query:
Time: 5 ms
Index: Auto/xz2MTg77IKTTb7MyHLD/4A==
Results: 25 returned out of 597 total.
尝试创建 CallRecords 的静态索引并像这样调用它:
session.Advanced.LuceneQuery<CustomerNameViewModel, Customers_ByName>()
.OrderByDescending("Name")
.Skip(0)
.Take(25)
.SetResultTransformer(new CustomerNameTransformer().TransformerName)
.ToList();
编辑:或像这样使用自动索引:
session.Advanced.LuceneQuery<CustomerNameViewModel>("Auto/Customers/ByName")
在我的例子中,Customer 就是您的 CallRecord。
这在 RavenDB 3.0.3599 中对我有效,但是,如果您使用的是 3.0,则应使用 DocumentQuery<> 而不是 LuceneQuery,因为后者已过时(但它有效)。
但是,我不确定这是 "correct" 的方法,但我找不到另一种方法来定义与 .SetResultTransformer 一起使用的 Transformer 的 return 类型(...)
希望对您有所帮助!
编辑:这是我的转换器,用奇怪的 LoadDocument 构建只是为了测试。所以它没有任何 "real" 意义:
public class CustomerNameTransformer : AbstractTransformerCreationTask<Customer>
{
public CustomerNameTransformer()
{
TransformResults = results => from customer in results
let fixture = LoadDocument<Fixture>(customer.FixtureNumber)
select new CustomerNameViewModel
{
Id = customer.Id,
Name = customer.Name,
FixtureNumber = fixture.FixtureNumber,
Customer = customer
};
}
}