Elasticsearch,精确文档匹配

问题描述 投票:0回答:1

我想在elasticsearch上执行精确匹配,但精确匹配应该在文档上而不是在搜索字符串上。例如:

我创建了这个索引:

PUT /indexName
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      }
    }
  }
}

POST /indexName/_doc
{
  "name": "City"
}

POST /indexName/_doc
{
  "name": "City Lab"
}

现在我想执行这样的搜索:

-如果我搜索(“城市”),我只想获取第一个文档,第二个文档不应该匹配,因为(“城市”)没有计算整个(“城市实验室”)。

-如果我搜索(“城市实验室”),我想获得第二个文档和第一个文档网,因为它与它们完全匹配。

-如果我搜索(“Citly Lab 在哪里”),我们有(“City”)并且我们有(“City Lab”),所以我也想同时获得它们。

-如果我搜索(“lab”),我将得到 0 个命中,因为 lab 不匹配任何内容。

-如果我搜索(“我在城市里面,然后我会去实验室”),我应该只得到第一个文档,(“城市”)是完全匹配的,但是(“我在里面” city,那么我会去lab”)(“city ... lab”),(“Lab”)不是直接在(“City”)之后,所以它不匹配。

如何在elasticsearch中做到这一点?

elasticsearch lucene solar
1个回答
0
投票

这需要特定的方法。我们需要使用不同的分析器来搜索和索引该字段。索引分析器将删除多余的空格和标点符号,将文本转换为小写,并将其索引为单个术语。同时,搜索分析器还将处理空格和标点符号处理,但它还会为每个单词、单词对、单词三元组等生成搜索词。

因此,在索引过程中,“City Lab”将成为单个标记

city lab
,而“City”将成为
city
。同时搜索“City Lab”时会变成查询:

city
lab
city lab

这样它将匹配索引标记

city lab
city
。同时,仅搜索“lab”将生成一个与任何内容都不匹配的标记
lab
。这是一个完整的例子:

DELETE test
PUT test
{
  "settings": {
    "max_shingle_diff": 4,
    "analysis": {
      "char_filter": {
        "whitespace_and_punct_to_single_space": {
          "type": "pattern_replace",
          "pattern": "[\\p{Punct}\\s]+",
          "replacement": " "
        }
      },
      "filter": {
        "name_shingles": {
          "type": "shingle",
          "min_shingle_size": 2,
          "max_shingle_size": 5,
          "output_unigrams": true
        }
      },
      "analyzer": {
        "name_index_analyzer": {
          "type": "custom",
          "char_filter": [
            "whitespace_and_punct_to_single_space"
          ],
          "tokenizer": "keyword",
          "filter": [
            "lowercase"
          ]
        },
        "name_search_analyzer": {
          "type": "custom",
          "char_filter": [
            "whitespace_and_punct_to_single_space"
          ],
          "tokenizer": "whitespace",
          "filter": [
            "lowercase",
            "name_shingles"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "name_index_analyzer",
        "search_analyzer": "name_search_analyzer"
      }
    }
  }
}

POST test/_bulk?refresh
{"index": {"_id": 1}}
{"name": "City"}
{"index": {"_id": 2}}
{"name": "City Lab"}

GET test/_search
{
  "query": {
    "match": {
      "name": "City"
    }
  }
}

GET test/_search
{
  "query": {
    "match": {
      "name": "City Lab"
    }
  }
}

GET test/_search
{
  "query": {
    "match": {
      "name": "Where is the City Lab?"
    }
  }
}

GET test/_search
{
  "query": {
    "match": {
      "name": "lab"
    }
  }
}

GET test/_search
{
  "query": {
    "match": {
      "name": "I am inside the city, then I will go to the lab"
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.