当前位置: 首页 > 工具软件 > ModeShape > 使用案例 >

java jcr_java – 通过JCR实现基于标签的搜索系统的最佳方式,如Modeshape

督宏旷
2023-12-01

有几种方法可以在JCR中实现标记.您选择哪个选项取决于您自己的应用程序的需求.以下是我所知道的四个选项.

选项1:使用Mixins

为每个标记定义一个mixin节点类型定义,它是一个标记mixin(它没有属性定义或子节点定义),使用NodeTypeManager动态注册它们.然后,当您想要“标记”节点时,只需向该节点添加表示标记的mixin.任何节点都可以有多个标记,您可以查询具有特定标记的所有节点.

(在此响应的其余部分中,“acme”用作通用名称空间.您应该将其替换为适合您自己的应用程序和组织的名称空间.)

例如,给定标记“acme:tag1”,您可以使用简单查询找到具有此标记的所有节点:

SELECT * FROM [acme:tag1]

这种方法的缺点是维护标签很麻烦.创建新标记需要注册新节点类型.您不能轻易地重命名标记,而是必须使用新名称为标记创建mixin;找到mixin代表旧标签的所有节点,删除旧的mixin,然后添加新的mixin;最后删除旧标记的节点类型定义(在任何地方不再使用之后).删除旧标签以类似的方式完成.另一个缺点是将附加元数据(例如,显示名称)与标签相关联并不容易,因为在节点类型定义上不允许额外的属性.

这种方法应该表现得很好.

选项2:使用分类法和强引用

在此方法中,您将在存储库的区域中创建一个简单的节点结构,您可以在其中为每个标记创建节点(例如,分类).在此节点上,您可以设置描述标记的属性(例如,显示名称);可以随时更改这些属性(例如,重命名标记).

然后,要将标记“应用”到节点,您只需要创建某种与标记的关系.一种方法是定义一个mixin节点类型,其中包含REFERENCE类型的“acme:tags”多值属性.如果要将一个或多个标记应用于节点,只需将mixin添加到节点,并将“acme:tags”属性设置为标记节点.

要查找特定标记的所有节点,可以在标记节点上调用“getReferences()”以查找包含对标记节点的引用的所有节点.

这种方法的好处是必须在一个或多个分类法(包括可能是用户特定的分类法)内控制/管理所有标签.但是,也有一些缺点.首先,REFERENCE属性的性能可能不是很好.一些JCR实现完全不鼓励使用REFERENCES. ModeShape没有,但是当有许多节点包含对同一节点的引用时(例如,许多具有单个标记的节点),ModeShape可能会开始降低REFERENCE性能.

选项3:使用分类法和弱引用

此选项与上面的选项2类似,但“acme:tags”属性为WEAKREFERENCE而不是REFERENCE.您仍然可以定义和管理一个或多个分类法.要查找具有特定标记的节点,您不能在标记节点上使用“getReferences()”方法(因为它们不适用于WEAKREFERENCE属性),但您可以使用查询轻松执行此操作:

SELECT * FROM [acme:taggable] AS taggable

JOIN [acme:tag] AS tag ON taggable.[acme:tags] = tag.[jcr:uuid]

AND LOCALNAME(tag) = 'tag1'

这种方法确实强制使用一个或多个分类法,使得控制标签更容易,因为它们必须存在于分类中才能使用.重命名和删除也更容易.性能方面,这比REFERENCE方法更好,因为WEAKREFERENCE属性在大量引用时表现更好,无论它们是指向一个节点还是多个节点.

缺点是您可以删除标记,即使它仍在使用,但包含对该删除标记的WEAKREFERENCE的节点将不再有效.这可以通过应用程序中的某些约定来解决,或者通过简单地使用分类法上的元数据来表示特定标记是“已弃用”且不应使用. (IMO,后者实际上是这种方法的一个好处.)

此选项通常比选项2更好地执行和扩展.

选项4:使用字符串属性

另一种方法是简单地使用STRING属性来标记每个节点以及要应用的标签的名称.例如,您可以定义一个mixin(例如,“acme:taggable”)来定义多值STRING属性,当您想要标记一个节点时,只需添加mixin(如果尚未存在)并添加名称标记为“acme:tags”STRING属性的值(同样,如果它尚未作为值存在).

这种方法的主要优点是它非常简单:您只是在要标记的节点上使用字符串值.要查找使用特定标记标记的所有节点(例如“tag1”),只需发出查询:

SELECT *

FROM [acme:taggable] AS taggable

WHERE taggable.[acme:tags] = 'tag1'

标签管理很简单:没有管理.如果要重命名标记,则可以重命名标记值.如果要删除标记(并从用其标记的节点中删除),则可以通过从“acme:tags”属性中删除值(可能在后台作业中)来完成.

请注意,这允许使用任何标记名称,因此最适用于根本不控制标记名称的情况.如果要控制用作标记值的字符串列表,只需在存储库中创建分类(如上面的选项2和3中所述),并让应用程序将值限制为分类中的值.您甚至可以拥有多个分类,其中一些可能是特定于用户的.但是这种方法与选项2或3没有完全相同的控制.

此选项将比选项3执行得更好(因为查询更简单),但也会扩展.

 类似资料: