file.filename 在 NEST 弹性搜索查询中返回 null

file.filename is returned null in NEST elastic search query

我想搜索内容字段以及 return 内容和文件名。下面的查询取自 NEST github page

连接字符串:

var node = new Uri("http://localhost:9200");
var settings = new ConnectionSettings(node);
var client = new ElasticClient(settings);

我的class:

搜索类型的class如下(感觉问题可能出在这里):

public class myclass
{
    public string Content { get; set; }
    public string filename { get; set; }
}

所以我只需要 file.filename 中的内容和文件名,但在我的搜索中 return 为 file.filename 为空,但内容在同一查询中为 return。

巢API呼叫:

var request = new SearchRequest
{
    From = 0,
    Size = 10,
    Query = new TermQuery { Name="Web", Field = "content", Value = "findthis" }
};

var response = client.Search<myclass>(request);
var twet = response.Documents.Select(t=>t.Content).ToList();

由于我是弹性搜索的新手所以无法理解。我什至不知道为什么我使用术语查询来搜索文档,而在 kibana 中我使用不同的查询和完全可以理解的匹配和 match_phrase 查询。所以请帮我得到 file.filename.

编辑:我也尝试将其包括在内(后来删除):

Source = new SourceFilter { Includes = ("file.filename") }

KIBANA 调用:

这是来自 kibana 控制台的调用:

GET /extract/_search
{
   "from" : 0, "size" : 1
    , "query": {
            "match": {
                        "content": "findthis"
                     }
               }
}

调用 return 后的结果我用了 1 个结果显示在这里:

弹性搜索索引中的文档:

{
  "took": 322,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 3330,
    "max_score": 4.693223,
    "hits": [
      {
        "_index": "extract",
        "_type": "doc",
        "_id": "29ebfd23bd7b276d7f3afc2bfad146d",
        "_score": 4.693223,
        "_source": {
          "content": """
                        my title
                        A looooong document text to findthis.
                    """,
          "meta": {
            "title": "my title",
            "raw": {
              "X-Parsed-By": "org.apache.tika.parser.DefaultParser",
              "Originator": "Microsoft Word 11",
              "dc:title": "my title",
              "Content-Encoding": "windows-1252",
              "Content-Type-Hint": "text/html; charset=windows-1252",
              "resourceName": "filename.htm",
              "ProgId": "Word.Document",
              "title": "my title",
              "Content-Type": "text/html; charset=windows-1252",
              "Generator": "Microsoft Word 11"
            }
          },
          "file": {
            "extension": "htm",
            "content_type": "text/html; charset=windows-1252",
            "last_modified": "2015-10-27T15:44:07.093+0000",
            "indexing_date": "2018-02-10T08:16:23.329+0000",
            "filesize": 32048,
            "filename": "filename.htm",
            "url": """file://D:\tmp\path\to\filename.htm"""
          },
          "path": {
            "root": "e1a38f7da342f641e3eefad1ed1ca0f2",
            "virtual": "/path/to/filename.htm",
            "real": """D:\tmp\path\to\filename.htm"""
          }
        }
      }
    ]
  }
}

我正在使用 NEST Api 从同一服务器上的弹性搜索 6 获取文档 file.filename

问题:

虽然我上面也提到了。问题是文件名在 NEST API 中为 returned null,而内容为 return.


解决方案 1: 使用 settings.DisableDirectStreaming(); 我检索了 JSON 结果并创建了 Following Class:

新建Class:

public class Rootobject
    {
        public int took { get; set; }
        public bool timed_out { get; set; }
        public _Shards _shards { get; set; }
        public Hits hits { get; set; }
    }

    public class _Shards
    {
        public int total { get; set; }
        public int successful { get; set; }
        public int skipped { get; set; }
        public int failed { get; set; }
    }

    public class Hits
    {
        public int total { get; set; }
        public float max_score { get; set; }
        public Hit[] hits { get; set; }
    }

    public class Hit
    {
        public string _index { get; set; }
        public string _type { get; set; }
        public string _id { get; set; }
        public float _score { get; set; }
        public _Source _source { get; set; }
    }

    public class _Source
    {
        public string content { get; set; }
        public Meta meta { get; set; }
        public File file { get; set; }
        public Path path { get; set; }
    }

    public class Meta
    {
        public string title { get; set; }
        public Raw raw { get; set; }
    }

    public class Raw
    {
        public string XParsedBy { get; set; }
        public string Originator { get; set; }
        public string dctitle { get; set; }
        public string ContentEncoding { get; set; }
        public string ContentTypeHint { get; set; }
        public string resourceName { get; set; }
        public string ProgId { get; set; }
        public string title { get; set; }
        public string ContentType { get; set; }
        public string Generator { get; set; }
    }

    public class File
    {
        public string extension { get; set; }
        public string content_type { get; set; }
        public DateTime last_modified { get; set; }
        public DateTime indexing_date { get; set; }
        public int filesize { get; set; }
        public string filename { get; set; }
        public string url { get; set; }
    }

    public class Path
    {
        public string root { get; set; }
        public string _virtual { get; set; }
        public string real { get; set; }
    }

查询: 我使用 MatchQuery 而不是 TermQuery 这是我的查询,连接字符串如上所示:

 var request = new SearchRequest
 {
     From = 0,
     Size = 1,
     Query = new MatchQuery { Field = "content", Query = txtsearch.Text }
 };

新问题: 我尝试了很多,虽然响应确实包含整个 JSON 结果,但它没有被正确映射。

我尝试使用 RootobjectHitsHit class,但结果仅 returned for _source 为:

var response = client.Search<_Source>(request);
var twet = response.Documents.Select(t => t.file.filename).ToList();

现在我可以检索 contentfile name,但如果我尝试使用以前的 classes。 Hitshits.total 被 return 编辑为 null

我尝试了以下查询:

var twet = response.Documents.SelectMany(t => t.hits.hits.Select(k => k._source.content)).ToList();

var twet1 = response.Hits.SelectMany(t => t.Source.hits.hits.Select(k => k._source.content)).ToList();

var twet1 = response.Documents.Select(t => t.Filename.fileName).ToList();

var twet = response.HitsMetadata.Hits.Select(t => t.Source.filename).ToList();

使用 RootobjectHitsHit class 等。虽然响应确实包含它。

那么我如何使用Rootobject class 来代替我想要的东西。

弹性搜索服务器 returns 响应为 JSON 字符串,然后 Nest 将其反序列化为您需要的 class.

在您的例子中,文件名是文件 属性 中的嵌套 属性。要反序列化嵌套的 JSON 属性,请检查此 link

public class MyClass
{
    public string Content { get; set; }
    public FileClass File { get; set; }
}

public class Fileclass
{
    public string Filename { get; set; }
}

然后你可以读取文件名 response.Documents.Select(t=>t.File.Filename).ToList();