我是ELastic搜索的新手。
elasticsearch中的数据在父子模型中。我想使用Java API在此数据中执行搜索。
父类型包含作者详细信息,子类型包含书籍详细信息,例如书籍名称,书籍出版商,书籍类别。
在搜索子项详细信息时,我还需要获取父项详细信息,反之亦然。有时,搜索条件将取决于父类型以及子类型。例如搜索由author1和撰写的书籍Fiction。
author1
Fiction
我如何在Java中实现呢?我已经参考了elasticsearch文档,但无法找到解决方案
请帮忙
首先使用parent/child映射设置索引。在下面的映射中,我还添加了一个未标记的字段,categories以便您可以对该字段执行过滤器查询。(对于创建索引和文档,我使用的是JSONAPI而不是JavaAPI,因为这不是问题的一部分。)
parent/child
categories
POST /test { "mappings": { "book": { "_parent": { "type": "author" }, "properties":{ "category":{ "type":"string", "fields":{ "raw":{ "type":"string", "index": "not_analyzed" } } } } } } }
创建一些author文档:
author
POST /test/author/1 { "name": "jon doe" } POST /test/author/2 { "name": "jane smith" }
创建一些book文档,指定请求之间book和之间的关系author。
book
POST /test/book/12?parent=1 { "name": "fictional book", "category": "Fiction", "publisher": "publisher1" } POST /test/book/16?parent=2 { "name": "book of history", "category": "historical", "publisher": "publisher2" } POST /test/book/20?parent=2 { "name": "second fictional book", "category": "Fiction", "publisher": "publisher2" }
下面的Java类执行3个查询:
books
authors
您可以从命令行运行该类,也可以将其导入Eclipse,然后右键单击该类,然后选择“运行方式> Java应用程序”。(您需要在类路径中有Elasticsearch库。)
import java.util.concurrent.ExecutionException; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.Client; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.index.query.FilterBuilders; import org.elasticsearch.index.query.HasChildQueryBuilder; import org.elasticsearch.index.query.HasParentQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.TermFilterBuilder; public class ParentChildQueryExample { public static void main(String args[]) throws InterruptedException, ExecutionException { //Set the Transport client which is used to communicate with your ES cluster. It is also possible to set this up using the Client Node. Settings settings = ImmutableSettings.settingsBuilder() .put("cluster.name", "elasticsearch").build(); Client client = new TransportClient(settings) .addTransportAddress(new InetSocketTransportAddress( "localhost", 9300)); //create the searchRequestBuilder object. SearchRequestBuilder searchRequestBuilder = new SearchRequestBuilder(client).setIndices("test"); //Query 1. Search on all books that have the term 'book' in the title and return the 'authors'. HasChildQueryBuilder bookNameQuery = QueryBuilders.hasChildQuery("book", QueryBuilders.matchQuery("name", "book")); System.out.println("Exectuing Query 1"); SearchResponse searchResponse1 = searchRequestBuilder.setQuery(bookNameQuery).execute().actionGet(); System.out.println("There were " + searchResponse1.getHits().getTotalHits() + " results found for Query 1."); System.out.println(searchResponse1.toString()); System.out.println(); //Query 2. Search on all authors that have the terms 'jon doe' in the name and return the 'books'. HasParentQueryBuilder authorNameQuery = QueryBuilders.hasParentQuery("author", QueryBuilders.matchQuery("name", "jon doe")); System.out.println("Exectuing Query 2"); SearchResponse searchResponse2 = searchRequestBuilder.setQuery(authorNameQuery).execute().actionGet(); System.out.println("There were " + searchResponse2.getHits().getTotalHits() + " results found for Query 2."); System.out.println(searchResponse2.toString()); System.out.println(); //Query 3. Search for books written by 'jane smith' and type Fiction. TermFilterBuilder termFilter = FilterBuilders.termFilter("category.raw", "Fiction"); HasParentQueryBuilder authorNameQuery2 = QueryBuilders.hasParentQuery("author", QueryBuilders.matchQuery("name", "jane smith")); SearchResponse searchResponse3 = searchRequestBuilder.setQuery(QueryBuilders.filteredQuery(authorNameQuery2, termFilter)).execute().actionGet(); System.out.println("There were " + searchResponse3.getHits().getTotalHits() + " results found for Query 3."); System.out.println(searchResponse3.toString()); System.out.println(); } }