在NEST弹性搜索查询

时间:2018-02-17 07:55:02

标签: elasticsearch json.net nest

我想搜索内容字段并返回内容和文件名。以下查询取自NEST github page

连接字符串:

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

我的班级:

搜索类型如下(我觉得问题可能在这里):

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

所以我只需要file.filename中的内容和文件名,但在我的搜索中,它为file.filename返回null,但内容确实在同一查询中返回。

NEST API CALL:

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"
                     }
               }
}

调用返回以下结果我在此处显示了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

ISSUE:

即使我上面已经提到了。问题是当内容确实返回时,NEST API中的filename返回null。

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

新班级:

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; }
    }

查询: 我在TermQuery使用MatchQuery而不是 var request = new SearchRequest { From = 0, Size = 1, Query = new MatchQuery { Field = "content", Query = txtsearch.Text } }; ,而不是我的查询,连接字符串如上所示:

Rootobject

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

我尝试使用HitsHit_source类,但仅为var response = client.Search<_Source>(request); var twet = response.Documents.Select(t => t.file.filename).ToList(); 返回结果:

content

现在我可以检索file nameHits但是如果我尝试使用以前的类。 hits.totalnull将返回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();

Rootobject

使用HitsHitRootobject类。虽然响应确实包含它。

那么我怎样才能使用<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="android:buttonStyle">@style/ButtonStyle</item> </style> 类来让我得到任何我想要的东西。

1 个答案:

答案 0 :(得分:2)

弹性搜索服务器将响应作为JSON字符串返回,然后将其反序列化为您所需的类。

在您的情况下,filename是文件属性中的嵌套属性。要反序列化嵌套的JSON属性,请检查此链接How to access nested object from JSON with Json.NET in C#

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();

这样的文件名