我有简单类型Question
:
public class Question
{
public Question(string id)
{
Id = id;
Tags = new List<string>();
}
public string Id { get; private set; }
public IList<string> Tags { get; set; }
}
我已经定义了这些问题的样本集:
var q1 = new Question("q1") { Tags = new List<string>() {"a"} };
var q2 = new Question("q2") { Tags = new List<string>() {"b"} };
var q3 = new Question("q3") { Tags = new List<string>() {"a", "b", "c"} };
var q4 = new Question("q4") { Tags = new List<string>() {"a", "b"} };
var q5 = new Question("q5") { Tags = new List<string>() {"z"} };
var q6 = new Question("q6");
var questions = new List<Question>() {q1, q2, q3, q4, q5, q6};
现在我需要从给定的子集中找到所有问题,其中至少包含一个标记。子集定义如下:
string[] tags = new[] {"a", "b"};
我希望返回 q1 , q2 , q3 和 q4 。我用来获得所需结果的查询是:
var questions = DocumentSession.Query<Question>().AsQueryable();
questions = GetQuestionsToContainingAtLeastOneTagFromSubset(questions, tags)
// some other query restrictions
var result = questions.ToList(); // (**)
假设对我的收藏施加限制的功能如下:
private IQueryable<Question> GetQuestionsToContainingAtLeastOneTagFromSubset(IQueryable<Question> questions, IEnumerable<string> tags)
{
var result = new List<Question>();
foreach (var tag in tags)
{
var currentTag = tag;
var resultForTag = questions.Where(x => x.Tags.Any(xTag => xTag == currentTag));
result = result.Concat(resultForTag).ToList();
}
return result.GroupBy(x => x.Id).Select(grp => grp.First()).AsQueryable();
}
我认为这是非常低效的。我想避免在提供的函数中使用.ToList()
。据我所知,.ToList()
表达式查询RavenDB并返回部分结果(BTW:我是对的吗?)。这效率不高。我只想在提供的函数中强加限制,并在强加所有限制后执行查询。 (**)
位置对我来说很有可能将批处理发送到RavenDB检索查询结果。
如何改进?
答案 0 :(得分:0)
试试这段代码:
var q1 = new Question("q1") { Tags = new List<string>() {"aa", "bb"} };
var q2 = new Question("q2") { Tags = new List<string>() {"aa"} };
var q3 = new Question("q3") { Tags = new List<string>() {"aa", "bb", "cc"} };
var q4 = new Question("q4");
var questions = new List<Question>() {q1, q2, q3, q4};
string[] tags = new[] { "bb", "cc" };
var res = (from p in questions where
(from q in tags where p.Tags.Contains(q) == true select p).ToArray().Count() >= 1
select p).Distinct();
//If you want more speed you can try to add .AsParallel() after .Distinct()
答案 1 :(得分:0)
你可以查询lucene以获得与yor tag aray array匹配的标记的问题:
string[] tags = new[] { "a", "b" };
string queryRange = "(" + string.Join(" OR ", tags) + ")";
var res = session.Advanced.LuceneQuery<Question>()
.Where("Tags:" + queryRange).ToList();
请注意,这会查询整个索引问题,而不是子集。但我认为你可以追加 - 我GUESS - 查询字符串表达式。 有关这些查询的更多信息,请参阅Lucene文档: http://lucene.apache.org/core/old_versioned_docs/versions/3_0_0/queryparsersyntax.html