c# – 如何使用NEST搜索ElasticSearch嵌套对象

我正在尝试使用NEST c#client搜索我的elasticsearch嵌套对象.
我的索引名称是人,我的类型是汽车领域嵌套的人.

这是我的班级:

using Nest;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WebApplication5
{
public class person
{
    public int id { get; set; }
    public String fname  { get; set; }
    public String mname { get; set; }
    public String lname { get; set; }
    public String houseno { get; set; }
    [ElasticProperty(Type = FieldType.Nested)]
    public IList<NestedType> car { get; set; } 
    public class NestedType
    {
        public String carname { get; set; }
        public int car_no { get; set; }
        public String color { get; set; }
    }
}

} 

现在我的Web应用程序看起来像这样:

using Elasticsearch.Net;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Configuration;
using Nest;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication5
{
public partial class WebForm1 : System.Web.UI.Page
{
    Stopwatch stopwatch = new Stopwatch();
    Uri node;
    ConnectionSettings settings;
    ElasticClient client;
    IList<person> list;
    protected void Page_Load(object sender, EventArgs e)
    {
        node = new Uri("http://localhost:9200");
        settings = new ConnectionSettings(node, defaultIndex:   "people");
        client = new ElasticClient(settings);
        list = new List<person>();

    }

    public IList<person> Search(ref long totalResult, int from,  int size, string searchKeyword)
    {
        list.Clear();
        stopwatch.Start();

        try
        {

            var result = client.Search<person> /*   */


  stopwatch.Start();
  totalResult = result.Total;
  list = result.Hits.Select(t => t.Source).ToList<person>();
  }
        catch (Exception ex)
        {
            string msg = ex.Message;
        }
 return 
            list;
    }
 protected void TextBox1_TextChanged(object sender, EventArgs e)
    {
        long totalResult = 0;
        IList<person> List = new List<person>();
        List = Search(ref totalResult, 0, 1000,TextBox1.Text);
        Label1.Text = "" + List.Count + " result(s)"+ " in "+ stopwatch.Elapsed.TotalSeconds+"seconds";
        GridView1.DataSource = List;
        GridView1.DataBind();
        List.Clear();

    }
  }
}

这里searchKeyword是我需要搜索的单词.
我在浏览器的搜索框(webform)中输入它.
searchKeyword可以包含任何需要与我的表人员中的任何字段的值匹配的值.
如果searchKeyword与嵌套文档匹配,则应返回确切的嵌套文档.
我不知道我的嵌套查询有什么问题,或者我实际上无法弄清楚如何使用嵌套查询来执行此操作.每次我运行应用程序并搜索实际存在于表中的值时,我得到零结果.请帮我弄清楚如何编写查询以在嵌套字段中搜索并帮助我检查我是否正确编写了类.
查询部分标记为/ * * /.
谁能帮我解决这个问题?

UPDATE
这是我的索引映射:

POST- people/person/_mapping
{
"person":{
"properties":{
  "car": {
    "type": "nested"
    }
  }
 }
}

我的记录看起来像这样:

POST-people/person
{
"id":1, 
"fname":"aditi",  
"mname":"ananya", 
"lname":"xyz", 
"houseno":"abc",
"car":
 [
  {
   "carname":"fiat",
   "carno":1234,
   "color":"white"
  },

  {
   "carname":"maruti",
   "carno":5678,
   "color":"silver"
  }
 ]
}


POST-people/person
{
"id":2, 
"fname":"robin",  
"mname":"kumar", 
"lname":"sharma", 
"houseno":"efg",
"car":
  [
   {
      "carname":"audi",
      "carno":4321,
      "color":"black"
   },

   {
      "carname":"honda",
      "carno":8765,
      "color":"red"
   },

   {
      "carname":"merecedez",
      "carno":0101,
      "color":"purple"
   }
 ]
}

这意味着我有2条记录.

第二次更新
我尝试了这个查询,它工作正常.虽然这不是我的最终查询.

POST-people/person/_search
{
"_source":false,
"query": {
"filtered": {
  "query": {"match_all": {}},
  "filter": {
    "nested": {
      "path": "car",
      "query":{
        "filtered": {
          "query": { "match_all": {}},
          "filter": {
            "and": [
              {"term": {"car.carname":"mercedez"}},
              {"term": {"car.color":"purple"}}
            ]
          }
        }
      },
"inner_hits":{}
    }
  }
 }
}
}

第三次更新
好的,所以现在在这种情况下,我的最终查询应该是:

{"_source":false,
"query": {
 "filtered": {
  "query": {"match_all": {}},
  "filter": {
    "nested": {
      "path": "car",
      "filter": {
        "term": {
          "car.carname": "audi"
        }
      }, 
      "inner_hits" : {}
    }
   }
  }
 }
}

我如何在.net中编写此查询?
这里,“_ source”和“inner_hits”对我来说很重要,因为我只想返回匹配的嵌套文档而没有别的东西(即我只想返回匹配的嵌套文档而不返回其他嵌套文档).
那么,能帮我写一下相应的搜索查询吗?
此外,这里我匹配car.carname字段,但我希望我的应用程序应该能够匹配汽车领域的所有其他子字段,如car.carno和car.color,甚至所有其他*id,fname等字段

第四次更新
在这里,我已经在.net中编写了搜索查询,用于我在第三次更新中提到的最终查询(请查看我的第三次更新).
你能检查一下它是否正确吗?
我写的.net中相应的最终查询是:

(s => s
 .Source(false)
   .Query(query => query.Filtered(filtered => filtered
    .Query(q => q.MatchAll())
      .Filter(f => f.Nested(nf => nf
        .InnerHits()
        .Path(p => p.car)
        .Query(qq => qq.Match(m => m.OnField(g=>g.car.First().carname).Query("audi"))))))));  

这就是我通过研究你的查询所写的内容(Thanx很多):).检查一下并告诉我是否有任何错误.但是,是的,我仍然无法找回任何结果.

解决方法:

尝试使用嵌套查询.

让我为测试目的索引一些数据:

client.Index(new Person
{
    Id = 1, 
    Car = new List<NestedType> {new NestedType {Carname = "car1"}}
});
client.Index(new Person
{
    Id = 2,
    Car = new List<NestedType> {new NestedType {Carname = "car1"}, new NestedType {Carname = "car2"}}
});
client.Index(new Person
{
    Id = 3,
    Car = new List<NestedType> { new NestedType {Carname = "car2"}}
});

client.Refresh();

现在,尝试这个嵌套查询:

var searchResponse = client.Search<Person>(s =>
    s.Query(q => q
        .Nested(n => n
            .Path(p => p.Car)
            .Query(qq => qq.Match(m => m.OnField(f => f.Car.First().Carname).Query("car2"))))));

搜索结果:

{
   "took": 10,
   "timed_out": false,
   "_shards": {..},
   "hits": {
      "total": 2,
      "max_score": 1.4054651,
      "hits": [
         {
            "_index": "my_index",
            "_type": "person",
            "_id": "2",
            "_score": 1.4054651,
            "_source": {
               "id": 2,
               "car": [
                  {
                     "carname": "car1",
                     "carNo": 0
                  },
                  {
                     "carname": "car2",
                     "carNo": 0
                  }
               ]
            }
         },
         {
            "_index": "my_index",
            "_type": "person",
            "_id": "3",
            "_score": 1,
            "_source": {
               "id": 3,
               "car": [
                  {
                     "carname": "car2",
                     "carNo": 0
                  }
               ]
            }
         }
      ]
   }
}

希望它能帮到你.

UPDATE

包括您的格式:

var searchResponse = client.Search<person>(s =>
    s.Query(q => q
        .Nested(n => n
            .Path(p => p.car)
            .Query(qq => qq.Match(m => m.OnField(f => f.car.First().carname).Query("car2"))))));

UPDATE2

根据您的更新,请尝试以下查询:

var searchResponse = client.Search<Person>(s => s
    .Query(query => query.Filtered(filtered => filtered
        .Query(q => q.MatchAll())
        .Filter(f => f.Nested(nf => nf
            .Path(p => p.Car)
            .Filter(filter => filter
                .And(
                    f1 => f1.Term(t => t.Car.First().Carname, "audi"),
                    f2 => f2.Term(t => t.Car.First().Color, "purple"))) 
            )))));

这会向elasticsearch生成此查询:

{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "nested": {
          "filter": {
            "and": {
              "filters": [
                {
                  "term": {
                    "car.carname": "audi"
                  }
                },
                {
                  "term": {
                    "car.color": "purple"
                  }
                }
              ]
            }
          },
          "path": "car"
        }
      }
    }
  }
}

UPDATE3

内部命中:

var searchResponse = client.Search<Person>(s => s
    .Source(false)
    .Query(query => query.Filtered(filtered => filtered
        .Query(q => q.MatchAll())
        .Filter(f => f.Nested(nf => nf
            .InnerHits()
            .Path(p => p.Car)
            .Filter(filter => filter
                .And(
                    f1 => f1.Term(t => t.Car.First().Carname, "audi"),
                    f2 => f2.Term(t => t.Car.First().Color, "purple")))
            )))));

注意:弹性搜索1.5.0中存在关于内部命中和过滤器的错误. Have a look.
如果你需要帮助来检索内部命中,请告诉我.

上一篇:【十分钟开发物联网】楼宇访客门禁管理(Wifi版)


下一篇:JS闭包由浅入深(热身一下)