簡體   English   中英

如何使用NEST在ElasticSearch嵌套對象中搜索

[英]How to search in ElasticSearch nested objects using NEST

我正在嘗試使用NEST c#客戶端搜索我的elasticsearch嵌套對象。 我的索引名稱是people ,類型是nested car person

這是我的課:

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是我需要搜索的單詞。
我在瀏覽器的搜索框(網絡表單)中輸入它。
searchKeyword可以包含任何需要與表person中任何字段的值匹配的值。
如果searchKeyword與嵌套文檔匹配,則應返回確切的嵌套文檔。
我不知道我的嵌套查詢有什么問題,或者我實際上不知道如何使用嵌套查詢來執行此操作。 每次我運行應用程序並搜索表中實際存在的值時,我都會得到零結果。 請幫助我弄清楚如何編寫query以在嵌套字段中進行搜索,並幫助我檢查是否正確編寫了class 查詢部分標記為/ * * /。 誰能幫我解決這個問題?

更新這是我的索引映射:

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字段的所有其他子字段(例如car.carnocar.color甚至所有其他頂級匹配。像idfname等字段。

第四次更新
在這里,我在.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"))))))));  

這是我通過研究您的查詢寫的(對此非常感謝:))。 請檢查並告訴我是否有任何問題。 但是,是的,我仍然無法獲取任何結果。

嘗試使用嵌套查詢。

讓我為測試目的索引一些數據:

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

希望對您有幫助。

更新

包括格式:

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

更新2

根據您的更新,嘗試以下查詢:

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

更新3

內在命中:

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

注意:elasticsearch 1.5.0中存在有關內部匹配和過濾器的錯誤。 看一看。 讓我知道您是否需要幫助來檢索內部匹配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM