ElasticSearch NEST词查询不返回结果

本文关键字:返回 结果 查询 NEST ElasticSearch | 更新日期: 2023-09-27 18:09:39

my schema

[ElasticType(Name = "importFile")]
public class ImportFile : DocumentMapping
{
    [ElasticProperty(Store = false, Index = FieldIndexOption.NotAnalyzed)]
    public string FileName { get; set; }
    [ElasticProperty(Store = false, Index = FieldIndexOption.NotAnalyzed)]
    public string GroupId { get; set; }
    [ElasticProperty(Store = false, Index = FieldIndexOption.Analyzed)]
    public string FilePath { get; set; }
}

我做了一个像这样的NEST查询:

    var res = ElasticClient.Search<ImportFile>(s => s
        .Index(ElasticIndexName)
        .Filter(f =>
            f.Term(t => t.FileName, "Group-1.uhh"))).Documents.ToArray();

并返回零元素!

如果我偷看db(使用postman),我可以看到我的文档:

{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 14.069489,
    "hits": [
      {
        "_index": "reviewer-bdd-test-index",
        "_type": "importFile",
        "_id": "AU9kUka2hr5Jg98UXOae",
        "_score": 14.069489,
        "_source": {
          "fileName": "Group-1.uhh",
          "groupId": "0ae1206d0644eabd82ae490e612732df5da2cd141fdee70dc64207f86c96094f",
          "filePath": ""
        }
      },
      {
        "_index": "reviewer-bdd-test-index",
        "_type": "importFile",
        "_id": "AU9kZO25hr5Jg98UXRnk",
        "_score": 14.069489,
        "_source": {
          "fileName": "group-1.uhh",
          "groupId": "0ae1206d0644eabd82ae490e612732df5da2cd141fdee70dc64207f86c96094f",
          "filePath": ""
        }
      }
    ]
  }
}

ElasticSearch NEST词查询不返回结果

听起来您可能没有在索引文档之前显式地将该类型的映射放入索引中,因此Elasticsearch根据它所看到的文档中字段的默认映射推断出该映射。例如,给定以下类型

[ElasticType(Name = "importFile")]
public class ImportFile
{
    [ElasticProperty(Store = false, Index = FieldIndexOption.NotAnalyzed)]
    public string FileName { get; set; }
    [ElasticProperty(Store = false, Index = FieldIndexOption.NotAnalyzed)]
    public string GroupId { get; set; }
    [ElasticProperty(Store = true, Index = FieldIndexOption.Analyzed)]
    public string FilePath { get; set; }
}

如果我们索引一些文档如下

void Main()
{
    var settings = new ConnectionSettings(new Uri("http://localhost:9200"));            
    var client = new ElasticClient(settings);
    client.Index<ImportFile>(
        new ImportFile{
            FileName = "Group-1.uhh",
            FilePath = "",
            GroupId = "0ae1206d0644eabd82ae490e612732df" + 
                      "5da2cd141fdee70dc64207f86c96094"
        },
        index => index
            .Index("reviewer-bdd-test-index")
            .Type("importFile")
            .Refresh());
    client.Index<ImportFile>(
        new ImportFile
        {
            FileName = "group-1.uhh",
            FilePath = "",
            GroupId = "0ae1206d0644eabd82ae490e612732df" + 
                      "5da2cd141fdee70dc64207f86c96094"
        },
        index => index
            .Index("reviewer-bdd-test-index")
            .Type("importFile")
            .Refresh());
    var results = client.Search<ImportFile>(s => s
                .Index("reviewer-bdd-test-index")
                .Type("importFile")
                .Query(q => q
                   .Filtered(fq => fq
                        .Filter(f => f
                            .Term(p => p.FileName, "Group-1.uhh")
                        )
                    )
                )
            );
    Console.WriteLine(string.Format("{0} {1}", results.RequestInformation.RequestMethod, results.RequestInformation.RequestUrl));
    Console.WriteLine(Encoding.UTF8.GetString(results.RequestInformation.Request)); 
    Console.WriteLine("Matching document count: {0}", results.Documents.Count());
}

控制台

的输出如下所示
POST http://localhost:9200/reviewer-bdd-test-index/importFile/_search
{
  "query": {
    "filtered": {
      "filter": {
        "term": {
          "fileName": "Group-1.uhh"
        }
      }
    }
  }
}
Matching document count: 0

我们没有得到匹配的文档。使用

检查Elasticsearch中的映射
curl -XGET "http://localhost:9200/reviewer-bdd-test-index/_mapping"
我们看到类型importFile的映射是
{
   "reviewer-bdd-test-index": {
      "mappings": {
         "importFile": {
            "properties": {
               "fileName": {
                  "type": "string"
               },
               "groupId": {
                  "type": "string"
               }
            }
         }
      }
   }
}

不是我们期望的;fileNamegroupId也应该有"index": "not_analyzed", filePath甚至不在映射中。这两个都是因为Elasticsearch已经根据它传递的文档推断了映射- fileNamegroupId已经被映射为字符串类型,并且将经过标准分析器的分析,而我相信 filePath没有被映射,因为两个看到的文档都有一个空字符串值的字段,所以标准分析器应用于该字段将不会产生任何令牌倒转索引。因此,该字段不包含在映射中。

因此,为了确保事情按预期工作,我们需要在索引任何文档

之前向索引添加映射。
void Main()
{
    var settings = new ConnectionSettings(new Uri("http://localhost:9200"));
    var client = new ElasticClient(settings);
    // Add the mapping for ImportFile to the index
    client.CreateIndex(indexSelector => indexSelector
        .Index("reviewer-bdd-test-index")
        .AddMapping<ImportFile>(mapping => mapping
            .MapFromAttributes()
        )
    );
    // ... Same as above after this point
}

结果是

POST http://localhost:9200/reviewer-bdd-test-index/importFile/_search
{
  "query": {
    "filtered": {
      "filter": {
        "term": {
          "fileName": "Group-1.uhh"
        }
      }
    }
  }
}
Matching document count: 1

成功!我们有一个匹配的文档。检查Elasticsearch中的映射会得到我们期望的结果

{
   "reviewer-bdd-test-index": {
      "mappings": {
         "importFile": {
            "properties": {
               "fileName": {
                  "type": "string",
                  "index": "not_analyzed"
               },
               "filePath": {
                  "type": "string",
                  "store": true
               },
               "groupId": {
                  "type": "string",
                  "index": "not_analyzed"
               }
            }
         }
      }
   }
}

另外,属性映射可以用流畅映射代替

var indexResult = client.CreateIndex(indexDescriptor => indexDescriptor
    .Index("reviewer-bdd-test-index")
    .AddMapping<ImportFile>(mapping => mapping
        .Type("importFile")
        .MapFromAttributes()
        .Properties(properties => properties
            .String(s => s
                .Name(file => file.FileName)
                .Store(false)
                .Index(FieldIndexOption.NotAnalyzed))
            .String(s => s
                .Name(file => file.GroupId)
                .Store(false)
                .Index(FieldIndexOption.NotAnalyzed))
            .String(s => s
                .Name(file => file.FilePath)
                .Store(true))
        )
    )
);

属性映射或流畅映射都可以做到这一点,但是有些事情只能通过流畅映射来实现,例如multi_fields