【问题标题】:Indexing of document in elastic search, JAVA API弹性搜索中的文档索引,JAVA API
【发布时间】:2015-09-05 02:39:25
【问题描述】:

我们正在使用弹性搜索 Java API 为简历文档编制索引。它工作正常。当我们搜索关键字时,它会返回包含该关键字的准确响应(文档)。

但我们想深入索引文档。例如,一份简历有“技能”和他们的“技能月”。技能月在文件中可能是 13 个月。所以我在弹性搜索查询中搜索该技能并将技能月设置为 10 到 15 个月,然后我们想要该记录(文档)。

我们怎样才能做到这一点?

这是索引的代码:-

IndexResponse response = client
                        .prepareIndex(userName, document.getType(),
                                document.getId())
                        .setSource(extractDocument(document)).execute()
                        .actionGet(); 

    public XContentBuilder extractDocument(Document document) throws IOException, NoSuchAlgorithmException {
        // Extracting content with Tika
        int indexedChars = 100000;
        Metadata metadata = new Metadata();

        String parsedContent;
        try {
            // Set the maximum length of strings returned by the parseToString method, -1 sets no limit
            parsedContent = tika().parseToString(new BytesStreamInput(
                Base64.decode(document.getContent().getBytes()), false), metadata, indexedChars);
        } catch (Throwable e) {
            logger.debug("Failed to extract [" + indexedChars + "] characters of text for [" + document.getName() + "]", e);
            System.out.println("Failed to extract [" + indexedChars + "] characters of text for [" + document.getName() + "]" +e);
            parsedContent = "";
        }

        XContentBuilder source = jsonBuilder().startObject();

        if (logger.isTraceEnabled()) {
            source.prettyPrint();
        }

        // File
        source
            .startObject(FsRiverUtil.Doc.FILE)
            .field(FsRiverUtil.Doc.File.FILENAME, document.getName())
            .field(FsRiverUtil.Doc.File.LAST_MODIFIED, new Date())
            .field(FsRiverUtil.Doc.File.INDEXING_DATE, new Date())
            .field(FsRiverUtil.Doc.File.CONTENT_TYPE, document.getContentType() != null ? document.getContentType() : metadata.get(Metadata.CONTENT_TYPE))
            .field(FsRiverUtil.Doc.File.URL, "file://" + (new File(".", document.getName())).toString());

        if (metadata.get(Metadata.CONTENT_LENGTH) != null) {
            // We try to get CONTENT_LENGTH from Tika first
            source.field(FsRiverUtil.Doc.File.FILESIZE, metadata.get(Metadata.CONTENT_LENGTH));
        } else {
            // Otherwise, we use our byte[] length
            source.field(FsRiverUtil.Doc.File.FILESIZE, Base64.decode(document.getContent().getBytes()).length);
        }
        source.endObject(); // File

        // Path
        source
            .startObject(FsRiverUtil.Doc.PATH)
            .field(FsRiverUtil.Doc.Path.ENCODED, SignTool.sign("."))
            .field(FsRiverUtil.Doc.Path.ROOT, ".")
            .field(FsRiverUtil.Doc.Path.VIRTUAL, ".")
            .field(FsRiverUtil.Doc.Path.REAL, (new File(".", document.getName())).toString())
            .endObject(); // Path

        // Meta
        source
            .startObject(FsRiverUtil.Doc.META)
            .field(FsRiverUtil.Doc.Meta.AUTHOR, metadata.get(Metadata.AUTHOR))
            .field(FsRiverUtil.Doc.Meta.TITLE, metadata.get(Metadata.TITLE) != null ? metadata.get(Metadata.TITLE) : document.getName())
            .field(FsRiverUtil.Doc.Meta.DATE, metadata.get(Metadata.DATE))
            .array(FsRiverUtil.Doc.Meta.KEYWORDS, Strings.commaDelimitedListToStringArray(metadata.get(Metadata.KEYWORDS)))
            .endObject(); // Meta


        // Doc content
        source.field(FsRiverUtil.Doc.CONTENT, parsedContent);

        // Doc as binary attachment
        source.field(FsRiverUtil.Doc.ATTACHMENT, document.getContent());

        // End of our document
        source.endObject();

        return source;
        }

以下代码用于获取响应:

QueryBuilder qb;
        if (query == null || query.trim().length() <= 0) {
            qb = QueryBuilders.matchAllQuery();
        } else {
            qb = QueryBuilders.queryString(query);//query is a name or string
        }
org.elasticsearch.action.search.SearchResponse searchHits =  node.client()
                .prepareSearch()
                .setIndices("ankur")
                .setQuery(qb)
                .setFrom(0).setSize(1000)
                .addHighlightedField("file.filename")
                .addHighlightedField("content")
                .addHighlightedField("meta.title")
                .setHighlighterPreTags("<span class='badge badge-info'>")
                .setHighlighterPostTags("</span>")
                .addFields("*", "_source")
                .execute().actionGet();

【问题讨论】:

  • 我们如何获得该文档的所有索引以便我们可以搜索特定字段?

标签: java elasticsearch-plugin elasticsearch


【解决方案1】:

默认情况下,弹性搜索索引所有列,以提供更好的搜索功能。在将 JSON 文档置于某种类型之前,最好先定义映射(参考:https://www.elastic.co/guide/en/elasticsearch/guide/current/mapping-analysis.html

当您想通过确切的关键字搜索数据时,您可能需要跳过特定列而不进行分析。在索引文档时,将分析列值,然后将其编入索引。您可以强制 Elastic 说“not_analyzed”。然后您的列值将按原样索引。这样您可以获得更好的搜索结果。

对于定义 JSON 文档的另一部分,最好使用一些库来定义 JSON。我更喜欢 Jackson 库来解析 JSON 文档。这将减少项目中的代码行数。

【讨论】:

    猜你喜欢
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 2018-07-21
    • 2015-06-01
    • 2016-10-08
    • 2022-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多