Solr,如何在schema.xml中定义嵌套文档

tyg4sfes  于 2022-11-05  发布在  Solr
关注(0)|答案(3)|浏览(231)

我有一个带有嵌套文档的文档,我想为Solr定义模式。我一直在阅读文档,但我不知道如何定义带有嵌套文档的schema.xml。
当我试图用addBean索引文档时,我得到一个错误,因为我在模式中没有字段obj1,而且我不知道如何定义它。
我使用的是带有@Field注解的java对象。

public class ObjToIndex {
    @Field
    String id;

    @Field
    String name;

    @Field
    ObjToIndex2 obj1;

public class ObjToIndex2 {
    @Field
    String id;
    @Field
    String lastName;

我不知道如何在模式中定义一个类型为“object”或类似类型的字段obj1

yh2wf1be

yh2wf1be1#

我不知道如何在模式中定义一个类型为“object”或类似类型的字段obj 1。
你不能(至少不是你认为的那样)
Solr并不是这样设计的:信息单元是由字段组成的文档;字段可以是不同的类型,但是,简而言之,它们只是基本类型(字符串、数字、布尔值),字段不能是复杂对象。
这是否意味着您不能管理嵌套文档?不。您可以通过一些 * 注意事项 * 来管理它们

如何定义模式

首先,您需要定义内部的_root_字段,如下所示:

<field name="_root_" type="string" indexed="true" stored="false" docValues="false" />

然后,您需要将父对象和子对象的所有“原始”字段合并到一个 * 单个 * 字段列表中。这有一些在solr文档中也提到的对应项:

  • 您必须定义一个ID字段,父对象和子对象都必须存在该字段,并且必须保证它是全局唯一的
  • 只有同时存在于父对象和子对象中的字段才能声明为“required”

例如,让我们看一个稍微复杂一点的例子,你可以嵌套多个评论到blog帖子:

public class BlogPost {
@Field
String id;

@Field
String title;

@Field(child = true)
List<Comment> comments;
}

public class Comment {
@Field
String id;

@Field
String content;
}

然后,您需要一个如下所示的模式:

<?xml version="1.0" encoding="UTF-8" ?>
<schema name="${solr.core.name}" version="1.5">
  <types>
    <fieldType name="string"  class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
    <fieldType name="long" class="solr.LongPointField" positionIncrementGap="0"/>

  <fields>   
    <field name="_version_" type="long" indexed="true" stored="true" />
    <field name="_root_" type="string" indexed="true" stored="false" docValues="false" />
    <field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true" />
    <field name="title" type="string" indexed="true" stored="true" multiValued="false" required="false" />
    <field name="content" type="string" indexed="true" stored="true" multiValued="false" required="false" />
  </fields>
  <uniqueKey>id</uniqueKey>
</schema>

如何为文档编制索引

使用solrj非常简单:只需在Java中创建嵌套对象,库就会在添加它们时创建正确的请求

final BlogPost myPost = new BlogPost();
myPost.id = "P1";
myPost.title = "My post";
final Comment comment1 = new Comment();
comment1.id = "P1.C1";
comment1.content = "My first comment";
final Comment comment2 = new Comment();
comment2.id = "P1.C2";
comment2.content = "My second comment";
myPost.comments = List.of(comment1, comment2);
...
solrClient.addBean("my_core", myPost);

如何检索文档

这有点棘手:要重建原始对象及其子对象,您必须在请求中使用子文档转换器(query.addField("[child]")):

final SolrQuery query = new SolrQuery("*:*");
    query.addField("*");
    query.addField("[child]");
    try {
        final QueryResponse response = solrClient.query("my_core", query);
        final List<BlogPost> documents = response.getBeans(BlogPost.class);
pobjuy32

pobjuy322#

为了具有嵌套对象,请使用@字段(child = true)

public class SolrBeanWithNested{

@Field
private String id;

@Field(child = true)
private MyNestedOject nested;

}

自solr 5.1起提供请参见门票:solr child

nfzehxib

nfzehxib3#

我相信这是正确的:
How to write nested schema.xml in solr?
“为什么”的一些逻辑被描述为here,但基本概念是,“子”文档实际上是同一模式中更“相关”或“链接”的文档。它们可能包括不同的字段,但实际上,它们只是添加到整个模式中的字段超集。

相关问题