具有相同类型文档的不同 RavenDB 集合

发布于 2024-11-29 07:30:42 字数 2132 浏览 4 评论 0原文

在 RavenDB 中,我可以存储“产品”和“类别”类型的对象,它们将自动位于不同的集合中。这很好。

但是,如果我有两种逻辑上完全不同类型的产品,但它们使用相同的类怎么办?或者我可以拥有通用数量的不同类型的产品,而不是 2 个。那么是否可以告诉 Raven 将产品文档拆分为集合,比如说基于 Product 类上可用的字符串属性?

先感谢您。

编辑: 我创建并注册了以下 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”是新的 raven 集合的名称(实体类型的名称也保存为 EntityData 对象上的单独字段)。

我将如何查询我的对象?在执行查询之前,我找不到可以在运行时定义集合的位置。

我是否必须执行一些原始 lucene 查询?或者我可以实现一个查询侦听器吗?

编辑: 我找到了一种使用动态定义的集合来存储、查询和删除对象的方法,但我不确定这是正确的方法:

文档存储侦听器:

(我使用上面定义的类)

解析索引名称的方法:

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

存储/查询/删除:

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

我感觉它有点脏,但这就是指定集合时存储/查询/删除的方式吗名称运行时?还是我就这样把自己困住了?

In RavenDB I can store objects of type Products and Categories and they will automatically be located in different collections. This is fine.

But what if I have 2 logically completely different types of products but they use the same class? Or instead of 2 I could have a generic number of different types of products. Would it then be possible to tell Raven to split the product documents up in collections, lets say based on a string property available on the Product class?

Thankyou in advance.

EDIT:
I Have created and registered the following StoreListener that changes the collection for the documents to be stored on runtime. This results in the documents correctly being stored in different collections and thus making a nice, logically grouping of the documents.

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

    }
}

However, it seems I have to adjust my queries too in order to be able to get the objects back. My typical query of mine used to look like this:

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

With the 'typeId' being the name of the new raven collections (and the name of the entity type saved as a seperate field on the EntityData-object too).

How would I go about quering back my objects? I can't find the spot where I can define my collection at runtime prioring to executing my query.

Do I have to execute some raw lucene queries? Or can I maybe implement a query listener?

EDIT:
I found a way of storing, querying and deleting objects using dynamically defined collections, but I'm not sure this is the right way to do it:

Document store listener:

(I use the class defined above)

Method resolving index names:

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

Store/Query/Delete:

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

I have the feeling its getting a little dirty, but is this the way to store/query/delete when specifying the collection names runtime? Or do I trap myself this way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

断肠人 2024-12-06 07:30:42

斯蒂芬,
您可以使用以下方法提供决定集合名称的逻辑:

 store.Conventions.FindTypeTagName

这是使用泛型类型静态处理的。
如果您想在运行时做出该决定,可以使用 DocumentStoreListner 提供它

Stephan,
You can provide the logic for deciding on the collection name using:

 store.Conventions.FindTypeTagName

This is handled statically, using the generic type.
If you want to make that decision at runtime, you can provide it using a DocumentStoreListner

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文