[英]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.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"))))))));
這是我通過研究您的查詢寫的(對此非常感謝:))。 請檢查並告訴我是否有任何問題。 但是,是的,我仍然無法獲取任何結果。
嘗試使用嵌套查詢。
讓我為測試目的索引一些數據:
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.