OpenSearch(ES)的入门教程-向量库

先开个篇

opensearch是aws根据Elasticsearch(ES)开发的一个组件,本文将讲解的入门教程。使用spring boot 2.5.3 和opensearch-java 1.0 JDK 开发

1、 先说使用es的比较重要,也是现在比较火的一个主要的功能, 向量库

向量的基础语法

  1. {
  2. "query": {
  3. "knn": {
  4. "embedding": {
  5. "vector": keyword_embedding,
  6. "k": k
  7. }
  8. }
  9. },
  10. "size": size
  11. }

java 构建ES的向量查询

  1. public Map<String, Double> getOpenSearchMap(String testStr) {
  2. if(StringUtils.isBlank(testStr)) return null;
  3. StopWatch stopWatch = new StopWatch();
  4. stopWatch.start();
  5. String embeddingData = this.getEmbeddingData(testStr);
  6. if(org.apache.commons.lang3.StringUtils.isBlank(embeddingData)) {
  7. log.error("embeddingData empty {}", embeddingData);
  8. return null;
  9. }
  10. // 构建 OpenSearch 查询
  11. String index = "/opensearch_index_embedding/_search";
  12. String jsonStart = "{\n" +
  13. " \"size\": 7,\n" +
  14. " \"query\": {\n" +
  15. " \"script_score\": {\n" +
  16. " \"query\": {\n" +
  17. " \"match_all\": {}\n" +
  18. " },\n" +
  19. " \"script\": {\n" +
  20. " \"source\": \"knn_score\",\n" +
  21. " \"lang\": \"knn\",\n" +
  22. " \"params\": {\n" +
  23. " \"field\": \"embedding_data\",\n" +
  24. " \"space_type\": \"cosinesimil\",\n" +
  25. " \"query_value\":";
  26. String jsonEnd = "}\n" +
  27. " }\n" +
  28. " }\n" +
  29. " }\n" +
  30. "}";
  31. String json = jsonStart+embeddingData+jsonEnd;
  32. // 执行查询
  33. OpenSearchCommonRes commonRes = opensearchUtils.queryByJson(index, "GET", json);
  34. stopWatch.stop();
  35. log.info("getOpenSearchMap,param:{},cost:{}",category,stopWatch.getTotalTimeMillis());
  36. // 处理查询结果
  37. if(Objects.nonNull(commonRes) && commonRes.getHits().getTotal().getValue()>0) {
  38. return commonRes.getHits().getHits().stream()
  39. .filter(p -> p.get_score() > 1.9d)
  40. .collect(Collectors.toMap(
  41. p -> p.get_source().get("category").toString(),
  42. p -> p.get_score(),
  43. (p1, p2) -> p1));
  44. }
  45. return null;
  46. }
  47. // 获取查询字段的具体 embedding的值
  48. private String getEmbeddingData(String testStr) {
  49. if(StringUtils.isBlank(testStr)) return null;
  50. StopWatch stopWatch = new StopWatch();
  51. stopWatch.start();
  52. String index = "/opensearch_index_embedding/_search";
  53. String jsonStart = "{\n" +
  54. " \"query\": {\n" +
  55. " \"term\": {\n" +
  56. " \"embedding_data\": {\n" +
  57. " \"value\": \"";
  58. String jsonEnd = "\"\n" +
  59. " }\n" +
  60. " }\n" +
  61. " },\n" +
  62. " \"_source\": [\"embedding_data\"]\n" +
  63. " \n" +
  64. "}";
  65. // 拼接查询字符串
  66. String json = jsonStart+testStr+jsonEnd;
  67. // 执行查询
  68. OpenSearchCommonRes commonRes = opensearchUtils.queryByJson(index, "POST", json);
  69. // 记录查询耗时
  70. if (commonRes == null || commonRes.getHits() == null || commonRes.getHits().getTotal() == null) {
  71. log.error("getEmbeddingData,testStr:{},result is null", testStr);
  72. return null;
  73. }
  74. stopWatch.stop();
  75. // 如果查询结果不为空且只有一个结果,返回该结果的 embedding_data 字段
  76. if(Objects.nonNull(commonRes) && commonRes.getHits().getTotal().getValue()==1) {
  77. return commonRes.getHits().getHits().stream().map(p -> p.get_source().get("embedding_data").toString()).findFirst().get();
  78. }
  79. return null;
  80. }

2、es中的搜索算法

  1. BM25算法
    1. BM25Best Matching 25)是一种基于概率检索框架的排名函数,用于估算文档和查询之间的相关性。它是TF-IDF(词频-逆文档频率)算法的改进版本,考虑了文档的长度和词频等因素,旨在解决TF-IDF在处理某些问题时的不足。


3、es中的基础的几个查询

普通查询

  1. _search

精确查找

  1. 精确查找

4、ES中的数据类型

  1. nested 查询
  2. {
  3. "unitCard": {
  4. "type": "nested",
  5. "properties": {
  6. "binNo": {
  7. "type": "text",
  8. "fields": {
  9. "keyword": {
  10. "type": "keyword",
  11. "ignore_above": 256
  12. }
  13. }
  14. },
  15. "color": {
  16. "type": "text",
  17. "fields": {
  18. "keyword": {
  19. "type": "keyword",
  20. "ignore_above": 256
  21. }
  22. }
  23. },
  24. "productName": {
  25. "type": "text",
  26. "fields": {
  27. "keyword": {
  28. "type": "keyword",
  29. "ignore_above": 256
  30. }
  31. }
  32. },
  33. "unitNo": {
  34. "type": "text",
  35. "fields": {
  36. "keyword": {
  37. "type": "keyword",
  38. "ignore_above": 256
  39. }
  40. }
  41. }
  42. }
  43. }
  44. }
点赞 ( 0 )

0 条评论

发表评论

人生在世,错别字在所难免,无需纠正。

插入图片
s
返回顶部