17

「タグ」のリストを含むドキュメント クラスがあります。何かのようなもの:

class Item {
  string Name { get; set; }
  List<string> Tags {get; set;}
}

ここで、タグのリストでフィルタリングされたすべてのアイテムを渡す RavenDB のクエリを作成したいと思います。Entity Framework を使用する場合、次のような方法でこれを行うことができました。

var query = GetQueryable();
foreach (var tag in tags)
{
   query = query.Where(i => i.Tags.Contains(tag));
}

ただし、これは RavenDB では機能しないようです。おそらく、Contains がサポートされていないためですWhere(i => i.Tags.Any(t=>t == tag))

Unable to cast object of type
'System.Linq.Expressions.PrimitiveParameterExpression`1[System.String]'
to type 'System.Linq.Expressions.MemberExpression

素晴らしいアイデアはありますか?私はこれを完全に間違っていますか?

4

1 に答える 1

17

Contains は実際にはまだサポートされていません (おそらくそうあるべきですが、それはまったく別の問題です。さまざまな演算子のサポートは、要求されたときにのみ追加します)

Anyに対する複数のクエリについては、動的データを実行しようとしていて、次のようなことを達成したいと考えています

"X OR Y OR Z"

これはトリッキーなものであり、LINQ プロバイダーはデフォルトでこれらの複数の WHERE 句を AND で集約するため、例は次のようになります

"X AND Y AND Z"

これは明らかに決してそうではありません。

これに対する最良のオプションは、Lucene クエリにドロップダウンして (少なくとも今のところ)、次のようにすることです。

var results = s.Advanced.LuceneQuery<Item>()
                   .Where(string.Format("Tags,:({0})", string.Join(" OR ", tags))); 

わかる?

上記のクエリは次のようになります

"Tags,:(X OR Y OR Z)"

注: 「タグ」は、タグが配列であることを RavenDB に通知します。

よし、[編集]!

実際に欲しいものを手に入れる最も簡単な方法は、これらの線に沿って何かをすることです

                new IndexDefinition<Item, Item>()
                {
                    Map = docs => from doc in docs
                                  select new
                                  {
                                      Tags = doc.Tags
                                  },
                    Indexes = {{ x => x.Tags, FieldIndexing.Analyzed }}
                }.ToIndexDefinition(store.Conventions));

次に、AND を照会するには、次のようにします。

                var results = s.Advanced.LuceneQuery<Item, WhateverYouCalledThatIndex>()
                   .Where(string.Format("Tags:({0})", string.Join(" AND ", tags)));

さて、気をつけたいこと

       Tags = doc.Tags

この例で機能するのは単なる文字列であるため、配列全体を 1 つの巨大なブロブにシリアル化します。

私はこれを表現するためのより良い方法を検討しています.LINQのような方法でこれを行うことはほとんどありません.実際にはうまくマッピングされていないためです.

少なくともできるようになりたいと思います

  Map = docs => from doc in docs
                                  select new
                                  {
                                      Tags = String.Join(" ", doc.Tags)
                                  },

(これはうまくいかないので、試さないでください)、達成したいことについてもう少し明確です。

于 2010-11-17T19:20:11.323 に答える