search - Elastic Search 父子数据搜索 Java API

标签 search elasticsearch java

我是 ELastic Search 的新手。

Elasticsearch 中的数据在父子模型中。我想使用 java api 对该数据执行搜索。

父类型包含作者详细信息,子类型包含书籍详细信息,如书籍名称、书籍出版商、书籍类别。

在对子详细信息执行搜索时,我还需要获取父详细信息,反之亦然。有时搜索条件将基于父类型和子类型。例如,搜索 author1 撰写的书籍并键入 Fiction

我如何在 Java 中实现它?我已经引用了 elastic search 文档,但无法获得解决方案

请帮忙

最佳答案

首先使用parent/child 映射设置您的索引。在下面的映射中,我还为 categories 添加了一个未标记的字段,因此您可以在该字段上执行过滤器查询。 (为了创建索引和文档,我使用的是 JSON API 而不是 Java API,因为这不是问题的一部分。)

POST /test
{
    "mappings": {
        "book": {
            "_parent": {
                "type": "author"
            },
            "properties":{
                "category":{
                    "type":"string",
                    "fields":{
                        "raw":{
                            "type":"string",
                            "index": "not_analyzed"
                        }
                    }
                }
            }
        }
    }
}

创建一些作者文档:

POST /test/author/1
{
    "name": "jon doe"
}


POST /test/author/2
{
    "name": "jane smith"
}

创建一些book文档,在请求中指定bookauthor之间的关系。

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 个查询:

  1. 搜索所有标题中包含术语“book”的书籍,然后 返回作者
  2. 搜索名称中包含术语“jon doe”的所有作者,并且 返回书籍
  3. 搜索由“jane smith”撰写且属于小说类型的书籍

您可以从命令行运行该类,或导入 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();
  }
}

关于search - Elastic Search 父子数据搜索 Java API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29116935/

相关文章:

search - 使用 Solr 的 log4j 日志索引

java - 按歌曲名称和艺术家姓名查找歌曲的算法,匹配最接近的字符串

elasticsearch - Kibana可视化中的聚合之聚合

java - 无法解析 Eclipse 中的 Neo4j 注释

Java 标准构建器查询不为空或为空

algorithm - 钉子接龙递归解决方案

linux - 查找包含字符串的文件,但几个文件夹除外

json - 在 Elasticsearch 中删除/添加嵌套对象

symfony - 自动完成+ elasticsearch + symfony2

java - 在 eclipse 中创建 org.jenkins-ci.plugins 时出现 maven-enforcer-plugin 问题