私は単純なタイプを持っています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};
次に、指定されたサブセットから、少なくとも1つのタグを含むすべての質問を見つける必要があります。サブセットは以下に定義されています。
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取得クエリ結果に送信するのに適しています。
それを改善する方法は?