【问题标题】:Elasticsearch multimatch filtered with list of Ids带有 ID 列表的 Elasticsearch 多匹配过滤器
【发布时间】:2020-02-07 20:31:33
【问题描述】:

我对 ES 比较陌生,我正在尝试解决以下问题。

我在我的 Elasticsearch 中使用以下配置创建了一个索引:

client.Indices.Create(lineItemIndex,
                c => c
                    .Settings(s => s
                        .Setting("max_ngram_diff", 13)
                        .Analysis(a => a
                            .Tokenizers(tf => tf
                                .NGram("mynGram", td => td
                                    .MaxGram(15).MinGram(2)))
                            .Analyzers(aa => aa
                                .Custom("mynGram_analyzer", ca => ca
                                    .Filters(new List<string> {"lowercase"})
                                    .Tokenizer("mynGram")))))
                    .Map<ElasticSearchLineItem>(m => m
                        .Properties(ps => ps
                            .Text(ss => ss
                                .Name(na => na.LineItemName)
                                .Fields(ff => ff
                                    .Keyword(k => k
                                        .Name("keyword"))
                                    .Text(tx => tx
                                        .Name("fulltext")
                                        .Analyzer("whitespace")
                                        .Boost(10.0))
                                    .Text(tx => tx
                                        .Name("partial")
                                        .Analyzer("mynGram_analyzer")
                                        .Boost(1.0)))))
                        .Properties(ps => ps
                            .Keyword(kw => kw
                                .Name(na => na.LineItemId)
                                .Index(false)))
                        .Properties(ps => ps
                            .Keyword(kw => kw
                                .Name(na => na.Id)
                                .Index(false)))
                        .Properties(ps => ps
                            .Text(ss => ss
                                .Name(na => na.LineItemNumber)
                                .Fields(ff => ff
                                    .Keyword(k => k
                                        .Name("keyword"))
                                    .Text(tx => tx
                                        .Name("fulltext")
                                        .Analyzer("whitespace")
                                        .Boost(10.0))
                                    .Text(tx => tx
                                        .Name("partial")
                                        .Analyzer("mynGram_analyzer")
                                        .Boost(1.0)))))
                        .Properties(ps => ps
                            .Keyword(ss => ss
                                .Name(na => na.SupplierName)
                                .Index(false)))
                        .Properties(ps => ps
                            .Keyword(ss => ss
                                .Name(na => na.Unit)
                                .Index(false)))
                        .Properties(ps => ps
                            .Number(ss => ss
                                .Name(na => na.PriceAmount)
                                .Type(NumberType.ScaledFloat).ScalingFactor(100)
                                .Index(false)))
                        .Properties(ps => ps
                            .Keyword(ss => ss
                                .Name(na => na.Currency)
                                .Index(false)))
                        .Properties(ps => ps
                            .Keyword(ss => ss
                                .Name(na => na.SupplierId)
                                .Index(false)))
                        .Properties(ps => ps
                            .Text(ss => ss
                                .Name(na => na.ImageUrl)
                                .Index(false)))
                        .Properties(ps => ps
                            .Text(ss => ss
                                .Name(na => na.SupplierPriceListId)
                                .Index(false)))));

我的解决方案是我们有一个搜索框,用于搜索。

但是,我们还假设能够根据SupplierId 过滤搜索。因此,进行搜索的人可能有多个 SupplierId,他们只想查看来自的结果。

我尝试创建以下查询:

var esSearch2 = new SearchDescriptor<ElasticSearchLineItem>()
            .From(0)
            .Take(250)
            .Query(q => q
                .Bool(b => b
                    .Must(mu => mu
                        .MultiMatch(m => m
                            .Fields(f => f
                                .Field(ff => ff
                                    .LineItemName.Suffix("fulltext"))
                                .Field(ff => ff
                                    .LineItemName.Suffix("partial"))
                                .Field(ff => ff
                                    .LineItemNumber.Suffix("fulltext"))
                                .Field(ff => ff
                                    .LineItemNumber.Suffix("partial")))
                        .Query(request.SearchWord)
                        .Fuzziness(Fuzziness.Auto)
                        ))                        
                    .Filter(f => f
                        .Terms(t => t
                            .Verbatim()
                            .Field(p => p
                                .SupplierId.Suffix("keyword"))
                            .Terms(request.ListOfFavorites.ToArray())))));

无论request.ListOfFavorites 是否为空,这都不会返回任何内容。但是如果我删除我的过滤器,它会正确返回结果。

我想我错过了什么,或者我的订单搞砸了。谁能帮帮我?

注意:我使用的是 ES 7.5.1 和 NEST 7.5.1

编辑:

我更改了我的索引,并从我的供应商 ID 字段中删除了 Index(false)

这里是更新后kibana中的映射

{
"mapping": {
"properties": {
  "currency": {
    "type": "keyword",
    "index": false
  },
  "id": {
    "type": "keyword",
    "index": false
  },
  "imageUrl": {
    "type": "text",
    "index": false
  },
  "lineItemId": {
    "type": "keyword",
    "index": false
  },
  "lineItemName": {
    "type": "text",
    "fields": {
      "fulltext": {
        "type": "text",
        "boost": 10,
        "analyzer": "whitespace"
      },
      "keyword": {
        "type": "keyword"
      },
      "partial": {
        "type": "text",
        "analyzer": "mynGram_analyzer"
      }
    }
  },
  "lineItemNumber": {
    "type": "text",
    "fields": {
      "fulltext": {
        "type": "text",
        "boost": 10,
        "analyzer": "whitespace"
      },
      "keyword": {
        "type": "keyword"
      },
      "partial": {
        "type": "text",
        "analyzer": "mynGram_analyzer"
      }
    }
  },
  "priceAmount": {
    "type": "scaled_float",
    "index": false,
    "scaling_factor": 100
  },
  "supplierId": {
    "type": "keyword"
  },
  "supplierName": {
    "type": "keyword",
    "index": false
  },
  "supplierPriceListId": {
    "type": "text",
    "index": false
  },
  "unit": {
    "type": "keyword",
    "index": false
  }
}
}
}

【问题讨论】:

    标签: c# elasticsearch nest


    【解决方案1】:

    在您的映射中,您将SupplierId 指定为excluded from the index,因此您将无法对其进行搜索。

    .Properties(ps => ps
        .Keyword(ss => ss
            .Name(na => na.SupplierId)
            .Index(false)))
    

    另外,你不需要为你的字段指定后缀,因为它没有被定义为多字段,所以简单

    .Filter(f => f
        .Terms(t => t
            .Verbatim()
            .Field(p => p.SupplierId)
            .Terms(request.ListOfFavorites.ToArray())))));
    

    够了。

    希望对您有所帮助。

    【讨论】:

    • 感谢您的建议。不幸的是,删除“Index(false)”并没有帮助
    • 更改后能否分享来自 elasticsearch 的索引映射?
    • 在删除 Index(false) 后,我进行了显示映射的编辑
    • 成功了。现在它似乎返回了结果 :) 现在我只需要在我的 ES 中获取更多 SupplierId 来查看过滤是否有效。
    • 不过有一个小问题。如果 ID 数组为空,则不返回任何内容。你有什么建议吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-06
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多