2012-11-09 37 views
2

因此,我成功創建了「包」對象的索引,並且直接轉發的文本查詢功能完美。在ElasticSearch上使用NEST - 我如何使用部分填充的對象作爲搜索條件

我很想知道是否/如何使用部分填充的對象(類型爲「Package」)作爲我的搜索條件?

包看起來像:

var packages = new List<Package> { 
      new Package { 
       Name = "Maverick", 
       TargetBusiness = new Business { 
        Industry = "Retail", 
        BusinessType = BusinessType.Product, 
        LocationType = LocationType.Store 
       }, 
       Description = "Standard package for retail shops" 
      }, 
      new Package { 
       Name = "Goose", 
       TargetBusiness = new Business { 
        Industry = "Retail", 
        BusinessType = BusinessType.Product, 
        LocationType = LocationType.Online 
       }, 
       Description = "Standard package for ecommerce shops" 
      }, 
      new Package { 
       Name = "Viper", 
       TargetBusiness = new Business { 
        Industry = "Advertising", 
        BusinessType = BusinessType.Service, 
        LocationType = LocationType.Office 
       }, 
       Description = "Standard package test retail" 
      } 
     } 

查詢目前看起來是這樣的:

var result = client.Search<Package>(x => x.Query(q => q.QueryString(qs => qs.Query("q=retail")))); 

但我還想有類似:

var result = client.Search<Package>(x => x.Query(q => q.Object(new Package{...etc ...}))); 

我希望我做感:D 在此先感謝

回答

2
var result = client.Search<Package>(x => x.Query(q => q.Object(new Package{...etc ...}))); 

不能工作,因爲Nest無法推斷對象上每個屬性(即term,prefix,wildcard,query_string等等)使用的查詢類型。

在您的示例中q=retail僅適用,因爲elasticsearch會將查詢拆分爲q OR retail。您可以使用常規的lucene語法來定位字段,例如targetBusiness.industry:retail

在elasticsearch中,如果您的查詢字符串未綁定到字段,它將默認搜索_all字段,該字段將包含對象所有屬性的所有字詞。這就是爲什麼如果你真的有大量的數據關閉_all支持通常是一個非常好的主意。

Nest目前沒有這樣的功能,它可以將部分填充的對象並將其轉換爲elasticsearch query_string查詢。

說,如果這是你的查詢:

client.Search<Package>(s=>s 
    .From(0) 
    .Size(10) 
    .Filter(f=> 
     f.Term(p=>p.TargetBusiness.Industry, "Advertising") 
     && f.Exists(p=>p.Name) 
    ) 
    .Query(q=> 
     q.QueryString(qs=>qs 
      .Query("ecommerce") 
      .Operator(Operator.and) 
     ) 
    ) 
) 

在上面的例子中,你必須創建自己的方法,讓所有的條款,根據您的包裹的查詢字符串查詢搜索。

public string MyPackageQueryString(Package package) 
{ 
    var myTerms = List<string>(); 
    myTerms.Add(package.Name); 
    if (package.TargetBusiness != null) 
    { 
     myTerms.Add(package.Industry) 
     .... 
    } 
    ... 
    return string.Join(" ", myTerms.Where(t=>!string.IsNullOrWhiteSpace(t))); 
} 

然後

client.Search<Package>(s=>s 
    .From(0) 
    .Size(10) 
    .Filter(f=> 
     f.Term(p=>p.TargetBusiness.Industry, "Advertising") 
     && f.Exists(p=>p.Name) 
    ) 
    .Query(q=> 
     q.QueryString(qs=>qs 
      .Query(this.MyPackageQueryString(package)) 
      .Operator(Operator.or) 
     ) 
    ) 
) 
+0

好吧,這意味着搜索每個財產對每一個其他財產權利? –

+0

是的,雖然你可以很容易地用「field:value」語法替換它,但這可能是要添加到NEST中的一些東西。我需要讓這個想法沉入一點:) –

0

真正幫助讓我在正確的軌道上 - 在一個看起來像某種交叉搜索結束:搜索每一個領域與其他所有領域我不想要。

端了(可能不正確地)要與:

return _searchClient.Search<Package>(s => s.Query(q => 
     q.Term("industry", criteriaPackage.TargetBusiness.Industry.ToLower()) || 
     q.Term("description", criteriaPackage.TargetBusiness.Description.ToLower()) || 
     q.Term("businessType",((int)criteriaPackage.TargetBusiness.BusinessType).ToString()) || 
     q.Term("locationType", ((int)criteriaPackage.TargetBusiness.LocationType).ToString()) || 
     q.Term("marketSegment", criteriaPackage.TargetBusiness.MarketSegment.ToLower()) || 
     q.Term("offer", criteriaPackage.TargetBusiness.Offer.ToLower())) 
    ).Documents; 

哪幾個單元測試後似乎產生的結果我是想。

相關問題