2016-09-19 2 views
0

У меня этот класс, назовем его «Устройство». Этот класс имеет несколько свойств, среди которых есть свойство коллекции (строковых значений).Query RavenDB для коллекции дочерних свойств, которая содержит определенное значение

В RavenDB может быть 5000 экземпляров «Устройство», где каждый из них МОЖЕТ иметь список значений строк в свойстве коллекции. Назовем это свойство «MyStringValues». Мой вопрос вращается вокруг наилучшего способа поиска ravendb для экземпляра устройства, который содержит строковое значение в свойстве коллекции.

Очень простой пример:

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 }; 
    } 
} 

Теперь вы можете запросить его любит:

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

Вот полный пример консольного приложения:

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)).

Затем загрузите все соответствующие документы либо с помощью потоковой передачи (если количество совпадающих записей может быть высоким), либо с помощью Load (вы знаете верхний предел загружаемых документов).

Чтобы проверить индекс в студии, вы можете запросить индекс, используя простой запрос MyStringValues:abc.

+0

Thanx для ответа ! Я должен быть честным и сказать, что я совершенно новичок в RavenDB. Как вы собираетесь создавать статический индекс в этом случае? – Nicke

Смежные вопросы