Запросите отдельную коллекцию в индексе RavenDB (ГДЕ IN) - PullRequest
2 голосов
/ 06 февраля 2020

Используя RavenDB v4.2 или выше, я хочу настроить индекс, который запрашивает другую коллекцию. По сути, воспроизводите предложение WHERE IN в отображаемой части индекса.

Представленные ниже модели представляют две коллекции. Здесь каждый User имеет коллекцию идентификаторов устройств:

class Device {
    public string Id { get; set; }
    public string Name { get; set; }
}

class User {
    public string Id { get; set; }
    public string BlogPostId { get; set; }
    public List<string> DeviceIds { get; set; } 
}

Теперь рассмотрим следующий индекс в качестве примера того, чего я пытаюсь достичь:

public class DeviceIndex : AbstractIndexCreationTask<Device, DeviceIndex.Result>
{
    public class Result
    {
        public string Id { get; set; }
        public string DeviceName { get; set; }
        public bool HasUser { get; set; }
        public int UserCount { get; set; }
    }
    public DeviceIndex()
    {
        Map = devices => from d in devices
                         select new Result
                         {
                             Id = d.Id,
                             DeviceName = d.Name,

                             HasUser = ... ?, // How to get this from Users collection?
                             UserCount = ... ? // same...

                         };

    }

Как мне заполнить HasUser true / false и UserCount свойства в этом индексе? Например, как я могу запросить здесь коллекцию «Пользователь»?

Обратите внимание, что этот пример серьезно упрощен для краткости. Меня не очень интересуют обходные пути или изменение логики c.

Ответы [ 2 ]

2 голосов
/ 18 февраля 2020

Как упомянул @Danielle, вам нужно использовать mutli-map-index и уменьшить результат. Вот рабочий пример

public class DeviceIndex : AbstractMultiMapIndexCreationTask<DeviceIndex.Result>
    {
        public class Result
        {
            public string Id { get; set; }
            public string DeviceName { get; set; }
            public bool HasUser { get; set; }
            public int UserCount { get; set; }
        }
        public DeviceIndex()
        {
            AddMap<User>(users => from u in users
                                  from deviceId in u.DeviceIds
                                  let d = LoadDocument<Device>(deviceId)
                                select new Result
                                {
                                    Id = d.Id,
                                    HasUser = true,
                                    UserCount = 1,
                                    DeviceName = d.Name,
                                });
            AddMap<Device>(devices => from d in devices
                                      select new Result
                                      {
                                          Id = d.Id,
                                          HasUser = false,
                                          UserCount = 0,
                                          DeviceName = d.Name,
                                      });

            Reduce = results => from result in results
                                group result by new { result.Id } into g
                                select new Result
                                {
                                    Id = g.First().Id,
                                    DeviceName = g.First().DeviceName,
                                    HasUser = g.Any(e => e.HasUser),
                                    UserCount = g.Sum(e => e.UserCount),
                                };

        }
    }

, и вы можете назвать его так

var result = await _session.Query<DeviceIndex.Result, DeviceIndex>().ToListAsync();
0 голосов
/ 06 февраля 2020

Если у вас есть список пользователей в устройстве , классе
List<string> Users
, который содержит идентификаторы документов из коллекции Users , тогда вы можете Индексируйте эти связанные документы.

См .: https://demo.ravendb.net/demos/csharp/related-documents/index-related-documents

Или сделайте обратное,
Создайте индекс для Пользователи сбор и индексирование соответствующего устройства info


Без изменения текущих моделей
Вы можете создать Multi-Map Index для индексации данные из разных коллекций.

https://ravendb.net/docs/article-page/4.2/csharp/indexes/multi-map-indexes

https://ravendb.net/docs/article-page/4.2/csharp/studio/database/indexes/create-multi-map-index

https://ravendb.net/learn/inside-ravendb-book/reader/4.0/10-static-indexes-and-other-advanced-options#querying -мани- источники, в однократной с-MultiMap-индексы

...