Различные коллекции RavenDB с документами одного типа - PullRequest
3 голосов
/ 13 августа 2011

В RavenDB я могу хранить объекты типа Продукты и Категории, и они будут автоматически размещаться в разных коллекциях. Это хорошо.

Но что, если у меня есть 2 совершенно разных типа продуктов, но они используют один и тот же класс? Или вместо 2 я мог бы иметь общее количество различных типов продуктов. Можно ли тогда сказать Raven разделить документы продукта на коллекции, скажем, на основе свойства строки, доступного в классе Product?

Спасибо заранее.

EDIT: Я создал и зарегистрировал следующий StoreListener, который изменяет коллекцию для документов, которые будут храниться во время выполнения. Это приводит к тому, что документы правильно хранятся в разных коллекциях и, таким образом, создается правильная логическая группировка документов.

public class DynamicCollectionDefinerStoreListener : IDocumentStoreListener
{
    public bool BeforeStore(string key, object entityInstance, RavenJObject metadata)
    {
        var entity = entityInstance as EntityData;
        if(entity == null)
            throw new Exception("Cannot handle object of type " + EntityInstance.GetType());
        metadata["Raven-Entity-Name"] = RavenJToken.FromObject(entity.TypeId);
        return true;
    }

    public void AfterStore(string key, object entityInstance, RavenJObject metadata)
    {

    }
}

Однако, похоже, мне тоже нужно скорректировать свои запросы, чтобы можно было вернуть объекты обратно. Мой типичный запрос раньше выглядел так:

session => session.Query<EntityData>().Where(e => e.TypeId == typeId)

При этом typeId - это имя новых коллекций воронов (и имя типа сущности, сохраняемое как отдельное поле в объекте EntityData).

Как мне поступить с просьбой вернуть мои объекты? Я не могу найти место, где я могу определить свою коллекцию во время выполнения до выполнения моего запроса.

Должен ли я выполнять некоторые необработанные запросы lucene? Или я могу реализовать прослушиватель запросов?

EDIT: Я нашел способ хранения, запроса и удаления объектов с использованием динамически определенных коллекций, но я не уверен, что это правильный способ сделать это:

Слушатель хранилища документов:

(я использую класс, определенный выше)

Метод разрешения имен индексов:

private string GetIndexName(string typeId)
{
    return "dynamic/" + typeId;
}

Магазин / Query / Удалить:

// Storing
session.Store(entity);

// Query
var someResults = session.Query<EntityData>(GetIndexName(entity.TypeId)).Where(e => e.EntityId == entity.EntityId)
var someMoreResults = session.Advanced.LuceneQuery<EntityData>(GetIndexName(entityTypeId)).Where("TypeId:Colors AND Range.Basic.ColorCode:Yellow)

// Deleting
var loadedEntity = session.Query<EntityData>(GetIndexName(entity.TypeId)).Where(e => 
e.EntityId == entity.EntityId).SingleOrDefault();
if (loadedEntity != null)
{
session.Delete<EntityData>(loadedEntity);
}

У меня такое ощущение, что он становится немного грязным, но это способ хранить / запрашивать / удалять при указании имен коллекций во время выполнения? Или я поймаю себя в ловушку таким образом?

1 Ответ

3 голосов
/ 15 августа 2011

Stephan, Вы можете предоставить логику для выбора имени коллекции, используя:

 store.Conventions.FindTypeTagName

Это обрабатывается статически, с использованием универсального типа.Если вы хотите принять это решение во время выполнения, вы можете предоставить его, используя DocumentStoreListner

...