弹性搜索弹簧

时间:2018-12-20 07:04:16

标签: java spring elasticsearch

我正在为基本的CRUD操作以及灵活的搜索功能开发一个spring应用程序。我正在使用弹性搜索作为后端数据存储。

以下是我正在处理的JSON文档:-

{
    "event-id":"7700908",
    "date":"date:time",
    "expiry": "some date",
    "created-by":"",
    "type":"x1|business|x3",
    ...
    "dress-code": {
        "mime-type": "image|audio|video|text",
        "placeholder-type": "key|index",
        "en_us": "Dress code guidelines...",
        "en_in": "",
        "placeholders": [
            {
                "key": "foo-bar",
                "type": "snippet|image|quote",
                "content": {
                    "mime-type": "image|audio|video|text",
                    "en_us": "some instruction placeholder",
                    "en_in": "some instruction placeholder",
                    "fr_FR": ""
                }
            }
        ]
    },
    "events": {
        "event-id": "4534534",
        "event-instruction": {
            "mime-type": "audio|video|text",
            "placeholder-type": "key|index",
            "en_us": "The actual instruction, with/without placeholder (like put of 3d glasses etc...)",
            "en_in": "",
            "placeholders": [
                {
                    "key": "foobar",
                    "type": "snippet|image|quote",
                    "content": {
                        "mime-type": "image|audio|video|text",
                        "en_us": "some instruction placeholder",
                        "en_in": "some instruction placeholder",
                        "fr_FR": ""
                    }
                }
            ]
        },
        "rules":""
        ...
    },
    "refs": [
        {
            "person-id":"445245524",
            ...
        }
    ]
}

然后下面的数据模型将在服务器上表示json以上:-

public class Event {

    @JsonProperty("event-id")
    private String eventId;

    @JsonProperty("date")
    private String date;

    @JsonProperty("expiry")
    private String expiry;

    @JsonProperty("created-by")
    private String createdBy;

    @JsonProperty("type")
    private String type;

    ...

    @JsonProperty("dress-code")
    private DressCode dressCode;

    ...
}

像往常一样,有 Controller Repository 类。控制器类定义了从url到服务器方法的映射,而存储库类实现了所有必要的数据库操作。

插入和获取记录是非常基本的。但是,我在基于用户提供的标准编写搜索功能时遇到了一些问题。以下是我的初始方法:-

public List<Map<String, Object>> getAllEventsForCriteria(final Event event) 
{

        List<Map<String, Object>> resultAsList = new ArrayList<>();
        SearchRequest searchRequest = new SearchRequest(INDEX);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(buildQuery(event));
        searchRequest.source(searchSourceBuilder);
        try {
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest);
            SearchHit[] searchHits = searchResponse.getHits().getHits();
            for (SearchHit hit : searchHits) {
                resultAsList.add(hit.getSourceAsMap());
            }
        } catch (java.io.IOException e) {
            e.getLocalizedMessage();
        }
        return resultAsList;
    }

    private QueryBuilder buildQuery(final Event event) {

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

        if (event.getEventId() != null) {
            QueryBuilder idTerm = QueryBuilders.termQuery("id", event.getQuizId());
            queryBuilder.must(idTerm);
        }
        if (event.getDate() != null) {
            QueryBuilder dateTerm = QueryBuilders.matchQuery("date", event.getDate());
            queryBuilder.must(dateTerm);
        }
        if (event.getExpiry() != null) {
            QueryBuilder expiryTerm = QueryBuilders.matchQuery("expiry", event.getExpiry());
            queryBuilder.must(expiryTerm);
        }
        if (event.getCreatedBy() != null) {
            QueryBuilder createdByTerm = QueryBuilders.matchQuery("created-by", event.getCreatedBy());
            queryBuilder.must(createdByTerm);
        }
        if (event.getType() != null) {
            QueryBuilder typeTerm = QueryBuilders.matchQuery("type", event.getType());
            queryBuilder.must(typeTerm);
        }
        if (event.getDressCode() != null) {
            if (event.getDressCode().getMimeType() != null) {
                QueryBuilder mimeTerm = QueryBuilders.termQuery("dressCode.mime-type", event.getDressCode().getMimeType());
                queryBuilder.must(mimeTerm);
            }
            if (event.getDressCode().getEnUs() != null) {
                QueryBuilder enUSTerm = QueryBuilders.matchQuery("dressCode.en_us", event.getDressCode().getEnUs());
                queryBuilder.must(enUSTerm);
            }
            if (event.getInstructions().getEnIn() != null) {
                QueryBuilder enInTerm = QueryBuilders.matchQuery("dressCode.en_in", event.getDressCode().getEnIn());
                queryBuilder.must(enInTerm);
            }
        }

        return queryBuilder;
    }

此方法面临两个主要问题:-

  • 用户可以根据参数的任意组合进行搜索。这种方法更一般吗?

  • 对于某些字段,我需要使搜索返回准确的结果。 matchQuery将返回所有结果,而termQuery将查询分为令牌。有/没有对JSON进行任何更改的出路是什么。

0 个答案:

没有答案