1

Schemaless Solr で Spring Data Solr をいじっています。接続できない点がいくつかあります: スキーマ フィールドはいつ、どのように作成されますか?

次のページの状態

アプリケーションのコンテキストが更新されるたびに、スキーマの自動作成によりドメイン タイプが検査され、プロパティの構成に基づいて新しいフィールドがインデックスに入力されます。これには、solr をスキーマレス モードで実行する必要があります。

@Indexed を使用して、使用する特定の solr タイプなどの追加の詳細を提供します。

また、curl リクエストも表示されます。

// curl ../solr/collection1/schema/fields -X POST -H 'Content-type:application/json'

ただし、@Indexed で注釈が付けられたフィールドで単純な例を実行すると、SOLR で呼び出されている /schema/fields API が表示されません。これらのフィールドはどのように作成されますか?

私が尋ねている理由は、それらが multiValued=true で自動的に作成されるように見えるからです。multiValued をパラメーターとして取る @Indexed アノテーションは見当たりませんでした。Spring Data Solr がフィールドを作成するときに非 multiValued として宣言するように強制するにはどうすればよいですか?

さて、これはすべて、私が見ているこの例外を解決するためのものです。

java.lang.IllegalArgumentException: [Assertion failed] - this argument is required; it must not be null
at org.springframework.util.Assert.notNull(Assert.java:115)
at org.springframework.util.Assert.notNull(Assert.java:126)
at org.springframework.data.solr.core.convert.MappingSolrConverter$SolrPropertyValueProvider.readValue(MappingSolrConverter.java:426)
at org.springframework.data.solr.core.convert.MappingSolrConverter$SolrPropertyValueProvider.readCollection(MappingSolrConverter.java:601)
at org.springframework.data.solr.core.convert.MappingSolrConverter$SolrPropertyValueProvider.readValue(MappingSolrConverter.java:440)
at org.springframework.data.solr.core.convert.MappingSolrConverter$SolrPropertyValueProvider.readValue(MappingSolrConverter.java:412)
at org.springframework.data.solr.core.convert.MappingSolrConverter$SolrPropertyValueProvider.getPropertyValue(MappingSolrConverter.java:395)
at org.springframework.data.solr.core.convert.MappingSolrConverter.getValue(MappingSolrConverter.java:206)
at org.springframework.data.solr.core.convert.MappingSolrConverter$1.doWithPersistentProperty(MappingSolrConverter.java:194)
at org.springframework.data.solr.core.convert.MappingSolrConverter$1.doWithPersistentProperty(MappingSolrConverter.java:186)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:309)
at org.springframework.data.solr.core.convert.MappingSolrConverter.read(MappingSolrConverter.java:186)
at org.springframework.data.solr.core.convert.MappingSolrConverter.read(MappingSolrConverter.java:174)
at org.springframework.data.solr.core.convert.MappingSolrConverter.read(MappingSolrConverter.java:149)
at org.springframework.data.solr.core.SolrTemplate.convertSolrDocumentListToBeans(SolrTemplate.java:560)
at org.springframework.data.solr.core.SolrTemplate.convertQueryResponseToBeans(SolrTemplate.java:552)
at org.springframework.data.solr.core.SolrTemplate.createSolrResultPage(SolrTemplate.java:369)
at org.springframework.data.solr.core.SolrTemplate.doQueryForPage(SolrTemplate.java:300)
at org.springframework.data.solr.core.SolrTemplate.queryForPage(SolrTemplate.java:308)
at org.springframework.data.solr.repository.support.SimpleSolrRepository.findAll(SimpleSolrRepository.java:111)
at org.springframework.data.solr.repository.support.SimpleSolrRepository.findAll(SimpleSolrRepository.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at 

値がコレクションとして返されているため、例外が発生していると思いますか?

何が起こっているのかを理解するために、コードをステップ実行しようとしました。問題を引き起こしているフィールドは「name」で、値は [product-1] です。Solr ドキュメントを POJO にアンマーシャリングしようとすると、例外が発生します。

まず、次のメソッドに入ります。

    private <T> T readValue(Object value, TypeInformation<?> type, Object parent) {
        if (value == null) {
            return null;
        }

        Assert.notNull(type);
        Class<?> rawType = type.getType();
        if (hasCustomReadTarget(value.getClass(), rawType)) {
            return (T) convert(value, rawType);
        }

        Object documentValue = null;
        if (value instanceof SolrInputField) {
            documentValue = ((SolrInputField) value).getValue();
        } else {
            documentValue = value;
        }

        if (documentValue instanceof Collection) {
            return (T) readCollection((Collection<?>) documentValue, type, parent);
        } else if (canConvert(documentValue.getClass(), rawType)) {
            return (T) convert(documentValue, rawType);
        }

        return (T) documentValue;

    }

このメソッドを呼び出す場合、値はコレクションで、型は java.lang.String です。これにより、if(documentValue instanceof Collection) が選択され、次のメソッドが実行されます。

        private Object readCollection(Collection<?> source, TypeInformation<?> type, Object parent) {
        Assert.notNull(type);

        Class<?> collectionType = type.getType();
        if (CollectionUtils.isEmpty(source)) {
            return source;
        }

        collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class;

        Collection<Object> items;
        if (type.getType().isArray()) {
            items = new ArrayList<Object>();
        } else {
            items = CollectionFactory.createCollection(collectionType, source.size());
        }

        TypeInformation<?> componentType = type.getComponentType();

        Iterator<?> it = source.iterator();
        while (it.hasNext()) {
            items.add(readValue(it.next(), componentType, parent));
        }

        return type.getType().isArray() ? convertItemsToArrayOfType(type, items) : items;
    }

このメソッドでは、最終的に type.getComponentType() を呼び出します。これは null を返し、最終的に Assert.notNull() を失敗させます。

このすべてで何が欠けていますか?

私のコードは次のとおりです。クラスの起動と構成:

@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableSolrRepositories(schemaCreationSupport=true, basePackages = { "com.example.solrdata" }, multicoreSupport = true)
public class Application {

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}
}

モデルクラス:

@SolrDocument(solrCoreName = "collection1")
public class Product {

@Id
String id;
@Indexed
String name;

public Product(String id, String name) {
    this.id = id;
    this.name = name;
}

public Product() {
    super();
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}}

リポジトリ:

public interface ProductRepository extends SolrCrudRepository<Product, String> {}

テストクラス:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class SolrProductRepositoryTest  {

@Autowired
private ProductRepository repo;

@Before @After
public void setup(){
    repo.deleteAll();
}

@Test
public void testCRUD() {
    assertEquals(0, repo.count());
    Product product = new Product("1","product-1");
    repo.save(product);
    assertEquals(1, repo.count());
    Product product2 = repo.findOne(product.getId());
    assertEquals(product2.getName(), product.getName());
}}

そして最後に、私のPOM:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.3.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-solr</artifactId>
    </dependency>
</dependencies>
4

1 に答える 1