如何跳过索引特定属性,但在Elasticsearch和NEST中查询时仍然检索其内容?

问题描述 投票:0回答:1

鉴于此索引模型类:

public class ProductIndexModel
{
    public Guid Id { get; set; }
    public DateTime Created { get; set; }
    public string Name { get; set; }
    public JObject DynamicContent { get; set; }
}

我正在努力做到以下几点:

  • 将整个对象存储在Elasticsearch中
  • 索引除DynamicContent属性之外的所有属性
  • 在查询时,检索整个对象(包括DynamicContent道具)

我没有索引DynamicContent属性的原因是,它是一个json-blob,偶尔会出现属性路径之间的冲突,这些冲突是不同类型的(例如,对象与字符串,int与字符串等等)。例如,尝试使用2个对象索引路径/dynamiccontent.id,其中value分别是int和string类型可能会给我:

错误:类型:mapper_parsing_exception原因:“无法解析[dynamiccontent.id]”CausedBy:类型:json_parse_exception原因:“当前令牌(START_OBJECT)不是数字,不能使用数值访问器

我以这种方式创建索引:

var createIndexResponse = await _elasticClient.CreateIndexAsync(indexName, c => c
    .InitializeUsing(settingsState)
    .Mappings(ms => ms
        .Map<ProductIndexModel>(m => m
            .AutoMap()
        )
    )
);

settingsState的类型为Nest.IndexState,带有一些标记符和更多,这与问题无关。

ISearchRequest SearchRequest(SearchDescriptor<ProductIndexModel> x) => x
    .Index(indexName)
    .Query(q => q.Bool(bq => bq.Filter(filters)))
    .From(filter.Offset)
    .Size(filter.PageSize)
;

var searchResponse = await _elasticClient.SearchAsync<ProductIndexModel>(SearchRequest);

其中filters是动态构建的过滤器通用列表,用于减少结果。

所以我想保持DynamicContent没有索引,但仍然能够在查询时获取其(原始)内容。

我试图用DynamicContent注释Nest.IgnoreAttribute,它完全抛弃它,因此在检索时产生一个空值。有关如何使用NEST“存储”值但不对其进行索引的任何建议?

elasticsearch nest
1个回答
1
投票

由于DynamicContent是Json.NET JObject类型,如果您使用的是NEST 6.x,则需要使用hook up the JsonNetSerializer才能正确索引JObject的实例。

连接此序列化程序后,您可以使用[Object(Enabled = false)]对模型进行归因,enabled=false for the field设置_source,这意味着该属性在JObject中保留但未解析或编入索引。

特别是使用"properties"时,NEST的自动化(在映射时需要考虑该属性)将为JObject生成一个大的private static void Main() { var defaultIndex = "default_index"; var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); var settings = new ConnectionSettings(pool, JsonNetSerializer.Default) .DefaultIndex(defaultIndex) .DefaultTypeName("_doc"); var client = new ElasticClient(settings); if (client.IndexExists(defaultIndex).Exists) client.DeleteIndex(defaultIndex); var createIndexResponse = client.CreateIndex(defaultIndex, c => c .Mappings(m => m .Map<ProductIndexModel>(mm => mm .AutoMap() // <-- automap .Properties(p => p .Object<JObject>(o => o .Name(n => n.DynamicContent) <-- override the automap inferred mapping for DynamicContent .Enabled(false) ) ) ) ) ); var indexResponse = client.Index(new ProductIndexModel { Id = Guid.NewGuid(), Created = DateTime.UtcNow, Name = "foo", DynamicContent = new JObject { { "prop1", "value1" }, { "prop2", new JArray(1, 2, 3, 4) } } }, i => i.Refresh(Refresh.WaitFor)); var searchResponse = client.Search<ProductIndexModel>(s => s .MatchAll() ); } public class ProductIndexModel { public Guid Id { get; set; } public DateTime Created { get; set; } public string Name { get; set; } [Object(Enabled = false)] public JObject DynamicContent { get; set; } } 对象,这是完全不必要的,因为该字段不会被解析或索引。在这种特殊情况下,流畅映射比属性映射更好。这是一个例子:

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.