#8 - Add MongoDB text search example.
The sample reads the Spring IO blog Atom feed and performs text search on it. We use manual index creation and query via MongoTemplate as well as automatic index creation and derived queries via repositories. Original pull request: #10.
This commit is contained in:
committed by
Oliver Gierke
parent
4246700be0
commit
09317bc6de
@@ -16,6 +16,7 @@ We have separate folders for the samples of individual modules:
|
||||
|
||||
* `geo-spatial` - Example project for general repository functionality (including geo-spatial functionality) and Querydsl integration
|
||||
* `aggregation` - Example project to showcase the MongoDB aggregation framework support.
|
||||
* `text-search` - Example project showing usage of MongoDB text search feature.
|
||||
|
||||
## Spring Data REST
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<modules>
|
||||
<module>geo-spatial</module>
|
||||
<module>aggregation</module>
|
||||
<module>text-search</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
||||
32
mongodb/text-search/README.md
Normal file
32
mongodb/text-search/README.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Spring Data MongoDB - Text Search Examples
|
||||
|
||||
This project contains samples of text search specific features of Spring Data Mongodb.
|
||||
|
||||
## Support for Text Index
|
||||
|
||||
Define text index structures manually (like below) or use `@TextIndexed` to mark content to be indexed for full text search.
|
||||
|
||||
```java
|
||||
TextIndexDefinition textIndex = new TextIndexDefinitionBuilder()
|
||||
.onField("title", 3F)
|
||||
.onField("content", 2F)
|
||||
.onField("categories")
|
||||
.build();
|
||||
|
||||
template.indexOps(BlogPost.class).ensureIndex(textIndex);
|
||||
```
|
||||
|
||||
## Support for full text repository queries
|
||||
|
||||
Use derived finder methods to search for terms and phrases.
|
||||
|
||||
```java
|
||||
interface BlogPostRepository extends CrudRepository<BlogPost, String> {
|
||||
|
||||
// page through results for full text query
|
||||
Page<BlogPost> findBy(TextCriteria criteria, Pageable page);
|
||||
|
||||
// find all matching documents and sort by relevance
|
||||
List<BlogPost> findAllByOrderByScoreDesc(TextCriteria criteria);
|
||||
}
|
||||
```
|
||||
26
mongodb/text-search/pom.xml
Normal file
26
mongodb/text-search/pom.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-data-mongodb-text-search</artifactId>
|
||||
|
||||
<name>Spring Data MongoDB - Text Search</name>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.examples</groupId>
|
||||
<artifactId>spring-data-mongodb-examples</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.rome</groupId>
|
||||
<artifactId>rome</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.mongodb.textsearch;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.index.TextIndexed;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.TextScore;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@Document
|
||||
public class BlogPost {
|
||||
|
||||
private @Id String id;
|
||||
private @TextIndexed(weight = 3) String title;
|
||||
private @TextIndexed(weight = 2) String content;
|
||||
private @TextIndexed List<String> categories;
|
||||
private @TextScore Float score;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public List<String> getCategories() {
|
||||
return categories;
|
||||
}
|
||||
|
||||
public void setCategories(List<String> categories) {
|
||||
this.categories = categories;
|
||||
}
|
||||
|
||||
public Float getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
public void setScore(Float score) {
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BlogPost [score=" + score + ", id=" + id + ", title=" + title + ", categories=" + getCategories() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.mongodb.textsearch;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mongodb.core.query.TextCriteria;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public interface BlogPostRepository extends CrudRepository<BlogPost, String> {
|
||||
|
||||
List<BlogPost> findAllBy(TextCriteria criteria);
|
||||
|
||||
List<BlogPost> findAllByOrderByScoreDesc(TextCriteria criteria);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.mongodb.textsearch;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
|
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
import example.springdata.mongodb.util.BlogPostInitializer;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@Configuration
|
||||
@EnableMongoRepositories
|
||||
public class MongoTestConfiguration extends AbstractMongoConfiguration {
|
||||
|
||||
static final String DATABASE_NAME = "s2gx2014-blog";
|
||||
static final String BLOG_POST_ATOM_FEED_SOURCE = "https://spring.io/blog.atom";
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
return DATABASE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mongo mongo() throws Exception {
|
||||
return new MongoClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the repository with a predefined set of entities.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public BlogPostInitializer initializer() {
|
||||
return new BlogPostInitializer(BLOG_POST_ATOM_FEED_SOURCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up after execution by dropping used test db instance.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@PreDestroy
|
||||
public void dropTestDB() throws Exception {
|
||||
mongo().dropDatabase(getDatabaseName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.mongodb.textsearch;
|
||||
|
||||
import static example.springdata.mongodb.util.ConsoleResultPrinter.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.core.query.TextCriteria;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { MongoTestConfiguration.class })
|
||||
public class TextSearchRepositoryTests {
|
||||
|
||||
@Autowired BlogPostRepository repo;
|
||||
|
||||
/**
|
||||
* Show how to do simple matching. <br />
|
||||
* Note that text search is case insensitive and will also find entries like {@literal releases}.
|
||||
*/
|
||||
@Test
|
||||
public void findAllBlogPostsWithRelease() {
|
||||
|
||||
TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingAny("release");
|
||||
List<BlogPost> blogPosts = repo.findAllBy(criteria);
|
||||
printResult(blogPosts, criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple matching using negation.
|
||||
*/
|
||||
@Test
|
||||
public void findAllBlogPostsWithReleaseButHeyIDoWantTheEngineeringStuff() {
|
||||
|
||||
TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingAny("release").notMatching("engineering");
|
||||
List<BlogPost> blogPosts = repo.findAllBy(criteria);
|
||||
printResult(blogPosts, criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Phrase matching looks for the whole phrase as one.
|
||||
*/
|
||||
@Test
|
||||
public void findAllBlogPostsByPhrase() {
|
||||
|
||||
TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingPhrase("release candidate");
|
||||
List<BlogPost> blogPosts = repo.findAllBy(criteria);
|
||||
printResult(blogPosts, criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort by relevance relying on the value marked with {@link org.springframework.data.mongodb.core.mapping.TextScore}.
|
||||
*/
|
||||
@Test
|
||||
public void findAllBlogPostsByPhraseSortByScore() {
|
||||
|
||||
TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingPhrase("release candidate");
|
||||
List<BlogPost> blogPosts = repo.findAllByOrderByScoreDesc(criteria);
|
||||
printResult(blogPosts, criteria);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.mongodb.textsearch;
|
||||
|
||||
import static example.springdata.mongodb.util.ConsoleResultPrinter.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.index.TextIndexDefinition;
|
||||
import org.springframework.data.mongodb.core.index.TextIndexDefinition.TextIndexDefinitionBuilder;
|
||||
import org.springframework.data.mongodb.core.query.TextCriteria;
|
||||
import org.springframework.data.mongodb.core.query.TextQuery;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
import example.springdata.mongodb.util.BlogPostInitializer;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class TextSearchTemplateTests {
|
||||
|
||||
MongoTemplate template;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
template = new MongoTemplate(new MongoClient(), MongoTestConfiguration.DATABASE_NAME);
|
||||
template.dropCollection(BlogPost.class);
|
||||
|
||||
createIndex();
|
||||
loadTestData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show how to do simple matching. <br />
|
||||
* Note that text search is case insensitive and will also find entries like {@literal releases}.
|
||||
*/
|
||||
@Test
|
||||
public void findAllBlogPostsWithRelease() {
|
||||
|
||||
TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingAny("release");
|
||||
List<BlogPost> blogPosts = template.find(query(criteria), BlogPost.class);
|
||||
printResult(blogPosts, criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort by relevance relying on the value marked with {@link org.springframework.data.mongodb.core.mapping.TextScore}.
|
||||
*/
|
||||
@Test
|
||||
public void findAllBlogPostsByPhraseSortByScore() {
|
||||
|
||||
TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingPhrase("release");
|
||||
|
||||
TextQuery query = new TextQuery(criteria);
|
||||
query.setScoreFieldName("score");
|
||||
query.sortByScore();
|
||||
|
||||
List<BlogPost> blogPosts = template.find(query, BlogPost.class);
|
||||
printResult(blogPosts, criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the mongodb text index for {@link BlogPost}. <br />
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* db.collection.ensureIndex(
|
||||
* {
|
||||
* "title" : "text"
|
||||
* "content" : "text"
|
||||
* "categories" : "text",
|
||||
* },
|
||||
* {
|
||||
* weights : {
|
||||
* "title" : 3,
|
||||
* "content" : 2
|
||||
* }
|
||||
* }
|
||||
* )
|
||||
* </code>
|
||||
* </pre>
|
||||
*/
|
||||
private void createIndex() {
|
||||
|
||||
TextIndexDefinition textIndex = new TextIndexDefinitionBuilder()//
|
||||
.onField("title", 3F) //
|
||||
.onField("content", 2F) //
|
||||
.onField("categories") //
|
||||
.build();
|
||||
|
||||
template.indexOps(BlogPost.class).ensureIndex(textIndex);
|
||||
}
|
||||
|
||||
private void loadTestData() throws Exception {
|
||||
|
||||
BlogPostInitializer initializer = new BlogPostInitializer(MongoTestConfiguration.BLOG_POST_ATOM_FEED_SOURCE);
|
||||
initializer.initialize(this.template);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.mongodb.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.sun.syndication.feed.atom.Category;
|
||||
import com.sun.syndication.feed.atom.Content;
|
||||
import com.sun.syndication.feed.atom.Entry;
|
||||
import com.sun.syndication.feed.atom.Feed;
|
||||
|
||||
import example.springdata.mongodb.textsearch.BlogPost;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class BlogPostInitializer implements InitializingBean {
|
||||
|
||||
private final String url;
|
||||
private final RestTemplate restTemplate;
|
||||
private final Converter<Entry, BlogPost> converter;
|
||||
|
||||
@Autowired MongoTemplate mongoTemplate;
|
||||
|
||||
public BlogPostInitializer(String url) {
|
||||
|
||||
restTemplate = new RestTemplate();
|
||||
this.converter = new EntryConverter();
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public void initialize(MongoTemplate mongoTemplate) {
|
||||
|
||||
ResponseEntity<Feed> feed = restTemplate.getForEntity(url, Feed.class);
|
||||
if (feed.hasBody()) {
|
||||
for (Object entry : feed.getBody().getEntries()) {
|
||||
if (entry instanceof Entry) {
|
||||
mongoTemplate.save(converter.convert((Entry) entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
initialize(this.mongoTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Converter} implementation capable of converting atom feed {@link Entry} into {@link BlogPost}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
static class EntryConverter implements Converter<Entry, BlogPost> {
|
||||
|
||||
@Override
|
||||
public BlogPost convert(Entry source) {
|
||||
|
||||
BlogPost post = new BlogPost();
|
||||
|
||||
post.setId(source.getId());
|
||||
post.setTitle(source.getTitle());
|
||||
|
||||
for (Object content : source.getContents()) {
|
||||
if (content instanceof Content) {
|
||||
post.setContent(((Content) content).getValue());
|
||||
}
|
||||
}
|
||||
|
||||
List<String> categories = new ArrayList<String>();
|
||||
for (Object category : source.getCategories()) {
|
||||
if (category instanceof Category) {
|
||||
categories.add(((Category) category).getLabel());
|
||||
}
|
||||
}
|
||||
post.setCategories(categories);
|
||||
|
||||
return post;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.mongodb.util;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.data.mongodb.core.query.TextCriteria;
|
||||
|
||||
import example.springdata.mongodb.textsearch.BlogPost;
|
||||
|
||||
/**
|
||||
* Just a little helper for showing {@link BlogPost}s output on the console.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class ConsoleResultPrinter {
|
||||
|
||||
public static void printResult(Collection<BlogPost> blogPosts, TextCriteria criteria) {
|
||||
|
||||
System.out.println(String.format("XXXXXXXXXXXX -- Found %s blogPosts matching '%s' --XXXXXXXXXXXX",
|
||||
blogPosts.size(), criteria != null ? criteria.getCriteriaObject() : ""));
|
||||
|
||||
for (BlogPost blogPost : blogPosts) {
|
||||
System.out.println(blogPost);
|
||||
}
|
||||
System.out.println("XXXXXXXXXXXX -- XXXXXXXXXXXX -- XXXXXXXXXXXX\r\n");
|
||||
}
|
||||
|
||||
}
|
||||
14
mongodb/text-search/src/test/resources/logback.xml
Normal file
14
mongodb/text-search/src/test/resources/logback.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="warn">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user