1)まず、私の場合にはアカウントで、ネストされたオブジェクトなどの製品を持っている一つのインデックスを持つことは良いアイデアですしかし、ここで私は毎回新しい製品を更新/追加したいのですが、私はアカウント文書全体を再索引付け(更新)する必要がありますか?
インデックスごとに1つのタイプと、in Elasticsearch 6.0+, you can only have one type per indexを持つことをお勧めします。製品がアカウントのネストされたオブジェクトとして表される場合、アカウントに新しい製品を追加するには、アプリケーションコード内の、またはElasticsearch内のいずれかのドキュメントを更新する必要があります。
2)私は検索機能を使用したいので、ユーザーがテキストボックスに入力して検索すると、アカウントと商品の両方でベストマッチを得たいと考えています(ここでは商品のタイトルその後、説明を加えたアカウントの名前と説明ベストマッチを得る):
あなたはthe documentation of covariant search resultsをチェックアウトし、複数のインデックス間で検索することができます。 1つのインデックスから複数の異なる型を返す例を示します(この例では6.0が更新されます)。これは複数のインデックスにわたって実行できます。ここでは例です:
private static void Main()
{
var settings = new ConnectionSettings(new Uri("http://localhost:9200"))
.InferMappingFor<AccountType>(i => i
.IndexName("account")
)
.InferMappingFor<ProductType>(i => i
.IndexName("product")
)
// useful for development, to make the request/response bytes
// available on the response
.DisableDirectStreaming()
// indented JSON in requests/responses
.PrettyJson()
// log out all requests/responses
.OnRequestCompleted(callDetails =>
{
if (callDetails.RequestBodyInBytes != null)
{
Console.WriteLine(
$"{callDetails.HttpMethod} {callDetails.Uri} \n" +
$"{Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)}");
}
else
{
Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}");
}
Console.WriteLine();
if (callDetails.ResponseBodyInBytes != null)
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n" +
$"{new string('-', 30)}\n");
}
else
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{new string('-', 30)}\n");
}
});
var client = new ElasticClient(settings);
if (client.IndexExists("account").Exists)
client.DeleteIndex("account");
client.CreateIndex("account", i => i
.Settings(s => s
.NumberOfShards(2)
.NumberOfReplicas(0)
)
.Mappings(m => m
.Map<AccountType>(map => map
.AutoMap()
.Properties(p => p
.Text(c => c
.Name(n => n.Name)
.Analyzer("standard")
)
.Text(c => c
.Name(n => n.Description)
.Analyzer("standard")
)
)
)
)
);
if (client.IndexExists("product").Exists)
client.DeleteIndex("product");
client.CreateIndex("product", i => i
.Settings(s => s
.NumberOfShards(2)
.NumberOfReplicas(0)
)
.Mappings(m => m
.Map<ProductType>(map => map
.AutoMap()
.Properties(p => p
.Text(c => c
.Name(n => n.Title)
.Analyzer("standard")
)
.Text(c => c
.Name(n => n.Description)
.Analyzer("standard")
)
)
)
)
);
client.IndexMany(new[] {
new AccountType { Name = "Name 1", Description = "Description 1" },
new AccountType { Name = "Name 2", Description = "Description 2" },
new AccountType { Name = "Name 3", Description = "Description 3" },
new AccountType { Name = "Name 4", Description = "Description 4" },
});
client.IndexMany(new[] {
new ProductType { Title = "Title 1", Description = "Description 1" },
new ProductType { Title = "Title 2", Description = "Description 2" },
new ProductType { Title = "Title 3", Description = "Description 3" },
new ProductType { Title = "Title 4", Description = "Description 4" },
});
var indices = Indices.Index(typeof(ProductType)).And(typeof(AccountType));
client.Refresh(indices);
var searchResponse = client.Search<object>(s => s
.Index(indices)
.Type(Types.Type(typeof(ProductType), typeof(AccountType)))
.Query(q => (q
.MultiMatch(m => m
.Fields(f => f
.Field(Infer.Field<ProductType>(ff => ff.Title, 1.5))
.Field(Infer.Field<ProductType>(ff => ff.Description, 0.8))
)
.Operator(Operator.Or)
.Query("Title 1")
) && +q
.Term("_index", "product")) || (q
.MultiMatch(m => m
.Fields(f => f
.Field(Infer.Field<AccountType>(ff => ff.Name, 3))
.Field(Infer.Field<AccountType>(ff => ff.Description, 0.3))
)
.Operator(Operator.Or)
.Query("Name 4")
) && +q
.Term("_index", "account"))
)
);
foreach (var document in searchResponse.Documents)
Console.WriteLine($"document is a {document.GetType().Name}");
}
public class ProductType
{
public string Title { get; set; }
public string Description { get; set; }
}
public class AccountType
{
public string Name { get; set; }
public string Description { get; set; }
}
結果が
document is a AccountType
document is a ProductType
document is a AccountType
document is a ProductType
document is a AccountType
document is a AccountType
document is a ProductType
document is a ProductType
で起こって多くはので、私が説明させてここにあります。
POST http://localhost:9200/product%2Caccount/producttype%2Caccounttype/_search?pretty=true
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"multi_match": {
"query": "Title 1",
"operator": "or",
"fields": [
"title^1.5",
"description^0.8"
]
}
}
],
"filter": [
{
"term": {
"_index": {
"value": "product"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"multi_match": {
"query": "Name 4",
"operator": "or",
"fields": [
"name^3",
"description^0.3"
]
}
}
],
"filter": [
{
"term": {
"_index": {
"value": "account"
}
}
}
]
}
}
]
}
}
}
検索はproducttype
とaccounttype
タイプで、両方product
とaccount
指数全体で実行されます。検索要求JSONは次のようになります。 title
フィールドとdescription
フィールドでmulti_matchクエリが実行され、boolクエリを使用する用語クエリと組み合わせて、クエリをproduct
インデックスに制約します。用語クエリに対して関連性スコアを計算しないため、クエリという用語はフィルタ句に含まれています。このbool照会は、name
およびdescription
フィールドでmult_match照会を実行する別のbool照会と組み合わされ、照会をaccount
索引に制約する用語照会でcmbinedされます。 2つのbool照会は、いずれかのbool照会または他の照会のいずれかが一致する必要があるため、句を使用して結合されます。
object
は
ProductType
と
AccountType
は、共通の基本クラスを共有していないので(!
object
以外)
Search<T>()
メソッド呼び出しのための一般的なパラメータの型として使用された文書コレクションを入力することができます。しかし、この結果から、NESTは
producttype
のインスタンスを
ProductType
のインスタンスに、
accounttype
のインスタンスを
AccountType
のドキュメントに実際に非直列化したことがわかります。
クエリでは、クエリをより簡潔に組み合わせるためにoperator overloadingが使用されます。
あなたは巣弾性検索のマスターです。私が質問をするたびに、私はあなたからの正確な答えを得ます。あなたのあまりにも詳細な答えにはとても感謝しています。 –
「地獄のような」願望はいいです:)助けて嬉しいです –
私の悪い英語のために申し訳ありません。それは "地獄のように"悪い意味を持っていると思われる –