2016-09-19 20 views
0

私はこのクラスを持っています。それを "デバイス"と呼んでください。このクラスには、(文字列値の)コレクションプロパティであるいくつかのプロパティがあります。特定の値を含む子プロパティコレクションのクエリRavenDB

RavenDBでは、「Device」のインスタンスが5000個あります。各インスタンスには、コレクションプロパティの文字列値のリストがあります。このプロパティを "MyStringValues"としましょう。 私の質問は、ravendbを検索してそのコレクションプロパティに文字列値を含むDeviceインスタンスを検索する最良の方法を中心にしています。

非常に単純な例:私は文字列値を渡す構築しようとする方法で

void Main() 
{ 
    var d1 = new Device(); 
    d1.Id = "device-1"; 
    d1.MyStringValues.Add("123"); 
    d2.MyStringValues.Add("456"); 

    var d2 = new Device(); 
    d2.Id = "device-2"; 
    d2.MyStringValues.Add("789"); 
    d2.MyStringValues.Add("abc"); 
} 

public class Device{ 
    public Device(){ 
     MyStringValues = new List<string>(); 
    } 
    public string Id {get;set;} 
    public IList<string> MyStringValues {get;set;} 
} 

。その文字列に基づいて、私はデバイスを受け取りたいです。 この「デバイス」を取得するにはどうすればよいでしょうか?デバイスの数は最大5000になる可能性があるので、それらをすべてフェッチしてループすることはできません。これを行うには、より良い(より速い)方法が必要です。 お元気ですか?

答えて

1

MyStringValuesリストに一致するインデックスを作成し、LINQのAnyを使用してクエリを実行することができます。

あなたのインデックスのようなものになります。今、あなたが好きそれを照会することができます

public class Devices_ByStringValue : AbstractIndexCreationTask<Device> 
{ 
    public override string IndexName => "Devices/ByStringValue"; 

    public Devices_ByStringValue() 
    { 
     Map = devices => from device in devices 
          select new { device.MyStringValues }; 
    } 
} 

:返信用

class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.Write("> Enter your search term: "); 

     var searchTerm = Console.ReadLine(); 

     using (var session = DocumentStoreHolder.Instance.OpenSession()) 
     { 
      var devices = session.Query<Device>() 
       .Where(x => x.MyStringValues.Any(s => s == searchTerm)) 
       .ToList(); 

      foreach (var device in devices) 
      { 
       Console.WriteLine(device.Id); 

       foreach (var s in device.MyStringValues) 
        Console.WriteLine($" - {s}"); 
      } 
     } 

     Console.ReadKey(); 
    } 
} 

public class Device 
{ 
    public Device() 
    { 
     MyStringValues = new List<string>(); 
    } 

    public string Id { get; set; } 
    public IList<string> MyStringValues { get; set; } 
} 

public class Devices_ByStringValue : AbstractIndexCreationTask<Device> 
{ 
    public override string IndexName => "Devices/ByStringValue"; 

    public Devices_ByStringValue() 
    { 
     Map = devices => from device in devices 
          select new { device.MyStringValues }; 
    } 
} 

public class DocumentStoreHolder 
{ 
    static DocumentStoreHolder() 
    { 
     Instance = new DocumentStore 
     { 
      Url = "http://localhost:8080/", 
      DefaultDatabase = "RavenTest", 
     }; 

     Instance.Initialize(); 
     Serializer = Instance.Conventions.CreateSerializer(); 
     Serializer.TypeNameHandling = TypeNameHandling.All; 

     Instance.Initialize(); 

     IndexCreation.CreateIndexes(typeof(Devices_ByStringValue).GetTypeInfo().Assembly, Instance); 
    } 

    public static DocumentStore Instance { get; } 

    public static JsonSerializer Serializer { get; } 
} 
0

MyStringValuesのデータを含むインデックスを作成します。各レコードの配列に複数の値を含めることができます。

次に、インデックスクエリを作成し、.Where(x => x.MyStringValues.Contains(filteredValue))を使用して特定の値を含むレコードのみをフィルタリングできます。

ストリーミング(一致するレコードの数が多い場合)またはロード(ロードするドキュメントの上限を知っている)を使用して、一致するすべてのドキュメントをロードします。

スタジオでインデックスをテストするには、単純なMyStringValues:abcクエリを使用してインデックスをクエリできます。

+0

ありがとう:ここ

var devices = session.Query<Device>() .Where(x => x.MyStringValues.Any(s => s == searchTerm)) .ToList(); 

は、完全なコンソールアプリケーションの例です。 !私は正直で、私はRavenDBの新機能だと言わなければなりません。この場合、静的インデックスを作成するにはどうしたらよいですか? – Nicke

関連する問題