当前位置: 首页 > 面试题库 >

Elastic search父子数据搜索Java API

柳英资
2023-03-14
问题内容

我是ELastic搜索的新手。

elasticsearch中的数据在父子模型中。我想使用Java API在此数据中执行搜索。

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

在搜索子项详细信息时,我还需要获取父项详细信息,反之亦然。有时,搜索条件将取决于父类型以及子类型。例如搜索由author1和撰写的书籍Fiction

我如何在Java中实现呢?我已经参考了elasticsearch文档,但无法找到解决方案

请帮忙


问题答案:

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

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

创建一些author文档:

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


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

创建一些book文档,指定请求之间book和之间的关系author

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. 搜索books标题中带有“ book”一词的所有内容,然后返回authors
  2. 搜索名称中所有authors带有“ jon doe”字样的内容,然后返回books
  3. 搜索books“ jane smith”写的且类型为Fiction的内容。

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


 类似资料:
  • 我使用Spring数据弹性搜索用于搜索/缓存目的。我需要执行一个使用child(TermCache)和parent(ConceptCache)属性的查询,并返回子对象的实例(这意味着我不能使用嵌套对象)。 我有以下结构: 我需要一个关于如何处理这类任务的提示;我应该使用两个单独的查询,还是应该以某种方式获取父对象的属性,或者其他什么?

  • 我正在使用elasticsearch elasticsearch-rails的官方gems套件,我在试图索引父/子关系时非常困难,我不确定我的问题是在映射、索引或查询还是在所有这些方面!!所以我不会发布我的代码片段。 是否有以下完整的工作示例: 子索引和父索引的映射 子级和父级的索引/更新/删除 在两个索引上查询高级查询;这意味着我需要用'has_child'查询在父索引上搜索,也需要用'has_

  • 我有以下elasticsearch 1.6.2索引映射:父项和子文档。一个项目可以有多个文档。文档没有嵌套,因为它们包含base64数据(mapper-attachments-plugin ),并且不能用项目更新。 我喜欢在两个索引中搜索,但总是返回项目。如果文档中存在匹配项,则返回相应的项。如果项目中存在匹配项,请返回该项目。如果两者都为真,则返回该项。 是否可以组合has_child和has_

  • 主要内容:多索引此API用于在Elasticsearch中搜索内容。 用户可以通过发送具有查询字符串的获取请求作为参数或在请求的消息正文中的查询来进行搜索。所有的搜索API都是多索引,多类型。 多索引 Elasticsearch允许我们搜索存在于所有索引或一些特定索引中的文档。 例如,如果我们需要搜索名称包含的所有文档。 响应 或者,同样地我们可以在,索引中搜索 - 多类型 还可以在所有类型或某种指定类型的索引中

  • 问题内容: 映射: 分行文件: 员工证件: 我想查找具有父ID的文档,我尝试了以下查询: 但是ES没有返回结果。如何在Elasticsearch中搜索具有相同父ID的子文档? 问题答案: 将在OP。有无效是没有叫父在外地类型。 以下是有效查询的示例:

  • 问题内容: 我刚开始使用ElasticSearch,却遇到了如何搜索的麻烦(我不一定要理解)。 首先,我有两个文件: 我想获取account.id =“ facundo @ facundo”和account.type =“ yojuego”的位置。我正在这样做: 该搜索将我拥有的所有文档检索到索引中。有什么帮助吗? 谢谢! PD:这是我创建索引和映射的方式: 问题答案: 确保该帐户是一个嵌套字段,