package org.xbib.elasticsearch.index.mapper.reference;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.index.IndexableField;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.DocumentMapperParser;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.xbib.elasticsearch.NodeTestUtils;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import static org.elasticsearch.common.io.Streams.copyToString;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.xbib.elasticsearch.MapperTestUtils.newDocumentMapperParser;
/**
*
*/
public class ReferenceMappingTests extends NodeTestUtils {
private static final Logger logger = LogManager.getLogger(ReferenceMappingTests.class.getName());
@Before
public void setupReferences() throws IOException {
startCluster();
try {
client().admin().indices().prepareDelete("test").execute().actionGet();
} catch (Exception e) {
logger.warn("unable to delete 'test' index");
}
client().prepareIndex("test", "test", "1234")
.setSource(jsonBuilder().startObject().array("myfield", "a","b","c").endObject())
.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
.execute().actionGet();
try {
client().admin().indices().prepareDelete("authorities").execute().actionGet();
} catch (Exception e) {
logger.warn("unable to delete 'authorities' index");
}
client().prepareIndex("authorities", "persons", "1")
.setSource(jsonBuilder().startObject().field("author", "John Doe").endObject())
.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
.execute().actionGet();
}
@After
public void cleanup() throws IOException {
stopCluster();
}
@Test
public void testRefMappings() throws Exception {
String mapping = copyToStringFromClasspath("ref-mapping.json");
DocumentMapperParser mapperParser = newDocumentMapperParser("someIndex");
DocumentMapper docMapper = mapperParser.parse("someType", new CompressedXContent(mapping));
BytesReference json = jsonBuilder().startObject()
.field("someField", "1234")
.endObject().bytes();
ParseContext.Document doc = docMapper.parse("someIndex", "someType", "1", json).rootDoc();
assertNotNull(doc);
for (IndexableField field : doc.getFields()) {
logger.info("testRefMappings {} = {}", field.name(), field.stringValue());
}
assertNotNull(docMapper.mappers().smartNameFieldMapper("someField"));
assertEquals("1234", doc.getFields("someField")[0].stringValue());
assertEquals(3, doc.getFields("ref").length);
assertEquals("a", doc.getFields("ref")[0].stringValue());
assertEquals("b", doc.getFields("ref")[1].stringValue());
assertEquals("c", doc.getFields("ref")[2].stringValue());
// re-parse from mapping
String builtMapping = docMapper.mappingSource().string();
docMapper = mapperParser.parse("someType", new CompressedXContent(builtMapping));
json = jsonBuilder().startObject()
.field("someField", "1234")
.endObject().bytes();
doc = docMapper.parse("someIndex", "someType", "1", json).rootDoc();
for (IndexableField field : doc.getFields()) {
logger.info("reparse testRefMappings {} = {}", field.name(), field.stringValue());
}
assertEquals("1234", doc.getFields("someField")[0].stringValue());
assertEquals(3, doc.getFields("ref").length);
assertEquals("a", doc.getFields("ref")[0].stringValue());
assertEquals("b", doc.getFields("ref")[1].stringValue());
assertEquals("c", doc.getFields("ref")[2].stringValue());
}
@Test
public void testRefInDoc() throws Exception {
String mapping = copyToStringFromClasspath("ref-mapping-authorities.json");
DocumentMapperParser mapperParser = newDocumentMapperParser("docs");
DocumentMapper docMapper = mapperParser.parse("docs", new CompressedXContent(mapping));
BytesReference json = jsonBuilder().startObject()
.field("title", "A title")
.field("dc.creator", "A creator")
.field("bib.contributor", "A contributor")
.field("authorID", "1")
.endObject().bytes();
ParseContext.Document doc = docMapper.parse("docs", "docs", "1", json).rootDoc();
for (IndexableField field : doc.getFields()) {
logger.info("testRefInDoc {} = {}", field.name(), field.stringValue());
}
assertEquals(2, doc.getFields("dc.creator").length);
assertEquals("A creator", doc.getFields("dc.creator")[0].stringValue());
assertEquals("John Doe", doc.getFields("dc.creator")[1].stringValue());
assertEquals(2, doc.getFields("bib.contributor").length);
assertEquals("A contributor", doc.getFields("bib.contributor")[0].stringValue());
assertEquals("John Doe", doc.getFields("bib.contributor")[1].stringValue());
}
@Test
public void testRefFromID() throws Exception {
String mapping = copyToStringFromClasspath("ref-mapping-from-id.json");
DocumentMapperParser mapperParser = newDocumentMapperParser("docs");
DocumentMapper docMapper = mapperParser.parse("docs", new CompressedXContent(mapping));
BytesReference json = jsonBuilder().startObject()
.field("title", "A title")
.field("authorID", "1")
.endObject().bytes();
ParseContext.Document doc = docMapper.parse("docs", "docs", "1", json).rootDoc();
assertEquals(1, doc.getFields("ref").length, 1);
assertEquals("John Doe", doc.getFields("ref")[0].stringValue());
}
@Test
public void testSearch() throws Exception {
try {
client().admin().indices().prepareDelete("books").execute().actionGet();
} catch (Exception e) {
logger.warn("unable to delete index 'books'");
}
client().admin().indices().prepareCreate("books")
.addMapping("test", copyToStringFromClasspath("ref-mapping-books-test.json"), XContentType.JSON)
.execute().actionGet();
client().prepareIndex("books", "test", "1")
.setSource(copyToStringFromClasspath("ref-doc-book.json"), XContentType.JSON)
.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).execute().actionGet();
// get mappings
GetMappingsResponse getMappingsResponse= client().admin().indices().getMappings(new GetMappingsRequest()
.indices("books")
.types("test"))
.actionGet();
MappingMetaData md = getMappingsResponse.getMappings().get("books").get("test");
logger.info("mappings={}", md.getSourceAsMap());
// search in field 1, unreferenced value
QueryBuilder queryBuilder = matchPhraseQuery("dc.creator", "A creator");
SearchResponse searchResponse = client().prepareSearch("books")
.setQuery(queryBuilder).execute().actionGet();
logger.info("unref hits = {}", searchResponse.getHits().getTotalHits());
for (SearchHit hit : searchResponse.getHits().getHits()) {
logger.info("{}", hit.getSource());
}
assertEquals(1, searchResponse.getHits().getTotalHits());
// search in field 1, referenced value
queryBuilder = matchPhraseQuery("dc.creator", "John Doe");
searchResponse = client().prepareSearch("books")
.setQuery(queryBuilder).execute().actionGet();
logger.info("ref hits = {}", searchResponse.getHits().getTotalHits());
for (SearchHit hit : searchResponse.getHits().getHits()) {
logger.info("{}", hit.getSource());
}
assertEquals(1, searchResponse.getHits().getTotalHits());
// search in field 2, unreferenced value
queryBuilder = matchPhraseQuery("bib.contributor", "A contributor");
searchResponse = client().prepareSearch("books")
.setQuery(queryBuilder).execute().actionGet();
logger.info("field 2 unref hits = {}", searchResponse.getHits().getTotalHits());
for (SearchHit hit : searchResponse.getHits().getHits()) {
logger.info("{}", hit.getSource());
}
assertEquals(1, searchResponse.getHits().getTotalHits());
// search in field 2, referenced value
queryBuilder = matchPhraseQuery("bib.contributor", "John Doe");
searchResponse = client().prepareSearch("books")
.setQuery(queryBuilder).execute().actionGet();
logger.info("field 2 ref hits = {}", searchResponse.getHits().getTotalHits());
for (SearchHit hit : searchResponse.getHits().getHits()) {
logger.info("{}", hit.getSource());
}
assertEquals(1, searchResponse.getHits().getTotalHits());
}
private String copyToStringFromClasspath(String path) throws IOException {
return copyToString(new InputStreamReader(getClass().getResource(path).openStream(), StandardCharsets.UTF_8));
}
}