【问题标题】:ElasticSearch Nest, edge n gram with FuzinessElasticSearch Nest,带有模糊性的边 n gram
【发布时间】:2020-11-23 12:27:24
【问题描述】:

我正在使用 ElastiSearch.Net 和 NEST v7.10.0 我有这些用于弹性搜索的设置和映射。

{
    "settings": {
        "index": {
            "analysis": {
                "filter": {},
                "analyzer": {
                    "keyword_analyzer": {
                        "filter": [
                            "lowercase",
                            "asciifolding",
                            "trim"
                        ],
                        "char_filter": [],
                        "type": "custom",
                        "tokenizer": "keyword"
                    },
                    "edge_ngram_analyzer": {
                        "filter": [
                            "lowercase"
                        ],
                        "tokenizer": "edge_ngram_tokenizer"
                    },
                    "edge_ngram_search_analyzer": {
                        "tokenizer": "lowercase"
                    }
                },
                "tokenizer": {
                    "edge_ngram_tokenizer": {
                        "type": "edge_ngram",
                        "min_gram": 2,
                        "max_gram": 50,
                        "token_chars": [
                            "letter"
                        ]
                    }
                }
            }
        }
    },
    "mappings": {
        "properties": {
            "MatchName": {
                "type": "text",
                "fields": {
                    "keywordstring": {
                        "type": "text",
                        "analyzer": "keyword_analyzer"
                    },
                    "edgengram": {
                        "type": "text",
                        "analyzer": "edge_ngram_analyzer",
                        "search_analyzer": "edge_ngram_search_analyzer"
                    },
                    "completion": {
                        "type": "completion"
                    }
                },
                "analyzer": "standard"
            },
            "CompetitionName": {
                "type": "text",
                "fields": {
                    "keywordstring": {
                        "type": "text",
                        "analyzer": "keyword_analyzer"
                    },
                    "edgengram": {
                        "type": "text",
                        "analyzer": "edge_ngram_analyzer",
                        "search_analyzer": "edge_ngram_search_analyzer"
                    },
                    "completion": {
                        "type": "completion"
                    }
                },
                "analyzer": "standard"
            }
        }
    }
}

我已经用值索引了 3 个文档

{
    "_source": {
        "CompetitionName": "Premiership",
        "MatchName": "Dundee Utd - St Johnstone",
    }
},
{
    "_source": {
        "CompetitionName": "2nd Div, Vastra Gotaland UOF",
        "MatchName": "IF Limhamn Bunkeflo - FC Rosengaard 1917",
    }
},
{
    "_source": {
        "CompetitionName": "Bundesliga",
        "MatchName": "Hertha Berlin - Eintracht Frankfurt",
    }
}

我正在使用 Fuziness.Auto 在字符串“bunde”的两个字段中进行搜索。 我想实现通过上面的搜索来获取所有文档。 但是对于下面的查询,我什么也得不到。

string value = "bunde";
BoolQuery boolQuery = new BoolQuery
{
    Should = new List<QueryContainer>
    {
        new QueryContainer(new FuzzyQuery
        {
            Field = Infer.Field<EventHistoryDoc>(path:eventHistoryDoc => eventHistoryDoc.MatchName),
            Value = value,
            Fuzziness = Fuzziness.Auto,
        }),
        new QueryContainer(new FuzzyQuery
        {
            Field = Infer.Field<EventHistoryDoc>(path:eventHistoryDoc => eventHistoryDoc.CompetitionName),
            Value = value,
            Fuzziness = Fuzziness = Fuzziness.Auto,
        })
    }
};

ISearchRequest searchRequest = new SearchRequest
{
    Query = new QueryContainer(boolQuery),
};

var json = _elasticClient.RequestResponseSerializer.SerializeToString(searchRequest);

ISearchResponse<EventHistoryDoc> searchResponse = await _elasticClient.SearchAsync<EventHistoryDoc>(searchRequest);

如果我用字符串“bundes”搜索,我只会得到一个文档

{
    "_source": {
        "CompetitionName": "Bundesliga",
        "MatchName": "Hertha Berlin - Eintracht Frankfurt",
    }
}

我应该对设置、映射或查询进行更改以获取上述所有文档的响应吗?

【问题讨论】:

    标签: c# elasticsearch nest


    【解决方案1】:

    我不知道 Elasticsearch Nest 的语法,但在 JSON 格式中,您可以通过以下方式获得结果:

    添加具有索引映射、搜索查询和搜索结果的工作示例 (目前,我已经从索引映射中删除了 keyword_analyzeredge_ngram_search_analyzer,因为您只想返回所有带有边缘 ngram 和模糊性的文档)

    索引映射:

    {
        "settings": {
            "analysis": {
                "analyzer": {
                    "my_analyzer": {
                        "tokenizer": "my_tokenizer"
                    }
                },
                "tokenizer": {
                    "my_tokenizer": {
                        "type": "edge_ngram",
                        "min_gram": 2,
                        "max_gram": 50,
                        "token_chars": [
                            "letter",
                            "digit"
                        ]
                    }
                }
            },
            "max_ngram_diff": 50
        },
        "mappings": {
            "properties": {
                "CompetitionName": {
                    "type": "text",
                    "analyzer": "my_analyzer"
                },
                "MatchName": {
                    "type": "text",
                    "analyzer": "my_analyzer"
                }
            }
        }
    }
    

    搜索查询:

    {
      "query": {
        "multi_match": {
          "query": "bunde",
          "fuzziness": "AUTO"
        }
      }
    }
    

    搜索结果:

    "hits": [
          {
            "_index": "64968421",
            "_type": "_doc",
            "_id": "1",
            "_score": 2.483365,
            "_source": {
              "CompetitionName": "Premiership",
              "MatchName": "Dundee Utd - St Johnstone"
            }
          },
          {
            "_index": "64968421",
            "_type": "_doc",
            "_id": "3",
            "_score": 2.4444416,
            "_source": {
              "CompetitionName": "Bundesliga",
              "MatchName": "Hertha Berlin - Eintracht Frankfurt"
            }
          },
          {
            "_index": "64968421",
            "_type": "_doc",
            "_id": "2",
            "_score": 0.6104546,
            "_source": {
              "CompetitionName": "2nd Div, Vastra Gotaland UOF",
              "MatchName": "IF Limhamn Bunkeflo - FC Rosengaard 1917"
            }
          }
        ]
    

    问题中提供的索引映射也是正确的。当使用相同的索引映射(如问题中提供的)并在多匹配查询中搜索bunde(如上所示)时,将返回所有三个文档(这是预期的结果)。

    【讨论】:

    • 你用的是什么版本的elasticsearch?对于您的更改,我的结果与以前完全相同。当我搜索“bunde”时,我没有得到任何结果,当我搜索“bundes”时,我得到 1 个 JSON 格式的文档。
    • @CHARISMEGALOS 我使用的是 Elasticsearch 7.8 版。当我搜索 bundebundes 时,我也在本地尝试过,我得到了所有三个文档(这是您的预期结果)
    • 我将 elastisearch 更新到 7.10.0,我对这两种方法都满意。非常感谢您的回答。我有 7.9.x
    • @CHARISMEGALOS 很高兴这对你有用?如果它帮助你解决你的问题你能不能接受并支持我的回答?
    猜你喜欢
    • 2011-07-03
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    相关资源
    最近更新 更多