简体   繁体   English

Spring 带约束的引导弹性搜索查询

[英]Spring Boot elastic Search Query with constraint

I am pretty new to this elastic search and spring boot world, I have been trying to search for this solution from past 2-3 days, sadly I was unable to (probably because I am new to this).我对这个弹性搜索和 spring 引导世界很陌生,我从过去的 2-3 天开始一直在尝试搜索这个解决方案,遗憾的是我无法(可能是因为我是新手)。

I have 3 columns inside elastic search, the first being the Id, second being name (upon which I am creating autocomplete API), and the third field with set of numbers called numbers.我在弹性搜索中有 3 列,第一列是 ID,第二列是名称(我在其上创建自动完成 API),第三个字段包含一组称为数字的数字。 My use case is that for a particular number in the 3rd column, I want autocomplete suggestions from 2nd column.我的用例是对于第 3 列中的特定数字,我想要来自第 2 列的自动完成建议。

This I have implemented with this code and it works: repo.findByNumbersAndName(String, String)我已经用这段代码实现了它并且它有效: repo.findByNumbersAndName(String, String)

But this does not allow me to set fuzziness, wildcardquery and other search parameter, so I tried using QueryBuilders but I am not successful in building logic (I basically tried using BooleanQueryBuilder), So if anyone can help me on this it would be really helpful!!但这不允许我设置模糊性、通配符查询和其他搜索参数,所以我尝试使用 QueryBuilders 但我在构建逻辑方面没有成功(我基本上尝试使用 BooleanQueryBuilder),所以如果有人可以帮助我这将非常有帮助!!

Spring boot version - 2.4.2 Spring 开机版本-2.4.2

Thanks in advance.提前致谢。

Edit1:-编辑1: -

To give better understanding of my use case, let say this is what I have stored in elastic Search为了更好地理解我的用例,假设这是我存储在弹性搜索中的内容

Id | Name   | Numbers |
-----------------------
a1 | ashwin | 1       |
a2 | Ram    | 3       |
a3 | Kumar  | 2       |
a4 | Some   | 2       |
a5 | body   | 1       |
a6 | any    | 3       |
a7 | one    | 4       |
a8 | ashwin | 2       |

Now I should have the control to specify my query saying that for this number (let's say 1), what are the autocomplete possibilities if input for autocomplete "a".现在我应该有控制权来指定我的查询,说对于这个数字(比如说 1),如果输入自动完成“a”,自动完成的可能性是什么。 Then the program should search for possibilities that have number "1" in the numbers column only, so in this scenario there is only one output that is "ashwin".然后程序应该只在数字列中搜索具有数字“1”的可能性,因此在这种情况下,只有一个 output 是“ashwin”。

Edit2:-编辑2: -

I believe my configuration and query method is same as what you have done, I will just paste what I have done.我相信我的配置和查询方法和你所做的一样,我只是粘贴我所做的。 One update is that though the Number field in database contains Integers but they are stored as String datatype, would that make any difference while term Query?一个更新是,虽然数据库中的 Number 字段包含 Integers,但它们存储为 String 数据类型,这在 term Query 时会有什么不同吗?

This is my elastic-analyzer.json这是我的弹性分析仪。json

{

  "analysis": {
    "filter": {
      "autocomplete_filter": {
        "type": "edge_ngram",
        "min_gram": 3,
        "max_gram": 30
      }
    },
    "analyzer": {
      "autocomplete_search": {
        "type": "custom",
        "tokenizer": "standard",
        "filter": [
          "lowercase",
          "stop"
          
        ]
      },
      "autocomplete_index": {
        "type": "custom",
        "tokenizer": "standard",
        "filter": [
          "lowercase",
          "autocomplete_filter",
          "stop"
        ]
      }
    }
  }
}

I am using this to generate a Query: -我正在使用它来生成查询:-

BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
        
        .must(QueryBuilders.termQuery("Number", number))
        .must(QueryBuilders.matchQuery("Name", search_word));

The above generates the query in this format -以上以这种格式生成查询 -

{
  "bool" : {
    "must" : [
      {
        "term" : {
          "Number" : {
            "value" : "1",
            "boost" : 1.0
          }
        }
      },
      {
        "match" : {
          "Name" : {
            "query" : "ash",
            "operator" : "OR",
            "prefix_length" : 0,
            "max_expansions" : 50,
            "fuzzy_transpositions" : true,
            "lenient" : false,
            "zero_terms_query" : "NONE",
            "auto_generate_synonyms_phrase_query" : true,
            "boost" : 1.0
          }
        }
      }
    ],
    "adjust_pure_negative" : true,
    "boost" : 1.0
  }

This is producing empty array, not able to understand why?这是产生空数组,不明白为什么? The below I feel is equivalent of properties that you had mentioned in Index Mapping我觉得下面的属性相当于您在索引映射中提到的属性

@Id
@Field(type = FieldType.Text)
private String Id;

@Field(type = FieldType.Text, analyzer = "autocomplete_index", searchAnalyzer = "autocomplete_search")
private String Name;

@Field(type = FieldType.Text)
private String Number;

Thanks @ESCoder谢谢@ECoder

Edit 3:-编辑3: -

I stumbled upon this with help from @ESCoder as well,在@ESCoder 的帮助下,我也偶然发现了这一点,

BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
        
        .must(QueryBuilders.matchQuery("Number", search_number).boost(1f).operator(Operator.AND))
        .must(QueryBuilders.matchQuery("Name", keyword).boost(0.4f));

This is the Query spring generated for ElasticSearch,这是为 ElasticSearch 生成的查询 spring,

{
  "bool" : {
    "must" : [
      {
        "match" : {
          "Number" : {
            "query" : "1",
            "operator" : "AND",
            "prefix_length" : 0,
            "max_expansions" : 50,
            "fuzzy_transpositions" : true,
            "lenient" : false,
            "zero_terms_query" : "NONE",
            "auto_generate_synonyms_phrase_query" : true,
            "boost" : 1.0
          }
        }
      },
      {
        "match" : {
          "Name" : {
            "query" : "ash",
            "operator" : "OR",
            "fuzziness" : "1",
            "prefix_length" : 0,
            "max_expansions" : 50,
            "fuzzy_transpositions" : true,
            "lenient" : false,
            "zero_terms_query" : "NONE",
            "auto_generate_synonyms_phrase_query" : true,
            "boost" : 0.4
          }
        }
      }
    ],
    "adjust_pure_negative" : true,
    "boost" : 1.0
  }
}

Adding a working example with index data, mapping, search query and search result添加带有索引数据、映射、搜索查询和搜索结果的工作示例

Index Mapping:索引映射:

{
  "settings": {
    "analysis": {
      "filter": {
        "autocomplete_filter": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 4
        }
      },
      "analyzer": {
        "autocomplete": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "autocomplete_filter"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "Name": {
        "type": "text",
        "analyzer": "autocomplete",
        "search_analyzer": "standard"
      },
      "Id": {
        "type": "text"
      },
      "Numbers": {
        "type": "integer"
      }
    }
  }
}

Index Data:指数数据:

{
  "Name": "ashwin",
  "Id": "a1",
  "Numbers": 1
}
{
  "Name": "ashwin",
  "Id": "a1",
  "Numbers": 2
}

Search Query:搜索查询:

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "Name": "a"
          }
        },
        {
          "term": {
            "Numbers": 1
          }
        }
      ]
    }
  }
}

Search Result:搜索结果:

"hits": [
      {
        "_index": "66923434",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.2630212,
        "_source": {
          "Name": "ashwin",
          "Id": "a1",
          "Numbers": 1
        }
      }
    ]

Update 1:更新1:

With your current index mapping setting, the following tokens are generated for ashwin使用您当前的索引映射设置,将为ashwin生成以下标记

GET /_analyze
{
  "analyzer" : "autocomplete",
  "text" : "ashwin"
}

Tokens are:令牌是:

{
  "tokens": [
    {
      "token": "ash",
      "start_offset": 0,
      "end_offset": 6,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "ashw",
      "start_offset": 0,
      "end_offset": 6,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "ashwi",
      "start_offset": 0,
      "end_offset": 6,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "ashwin",
      "start_offset": 0,
      "end_offset": 6,
      "type": "<ALPHANUM>",
      "position": 0
    }
  ]
}

You need to modify your index mapping, instead of "min_gram": 3 you need to change it to "min_gram": 1 .您需要修改索引映射,而不是"min_gram": 3您需要将其更改为"min_gram": 1

Update 2:更新 2:

You need to even change "search_analyzer" to standard .您甚至需要将"search_analyzer"更改为standard

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM