用ES做搜索,内容都在父子两张表(父一对多子),在设计logstash同步方案时候,碰到不少坑.
很多都是中文资料的无人区,摸索了很多时间,特此记录.
父表字段搜索比较简单,match,range,boost,关键词都能直接用
子表有枚举值,我用group_concat聚合到逗号分隔的字段上面,
同时在es的/_template下面,给索引加模板,聚合字段用自定义的逗号分词器,需要距离搜索的字段改成geo_point型(logstash也要加上
add_field => {"location" => "%{latitude},%{longitude}" })
这样一来,大多数对子表的搜索都能match到 (比如搜索子表类型包含A的父表数据,group_concat后是A,AB,AC,查询时候查A就能查到)
其实大多数需求这样就能解决了.但是变态的来了,需要对子表的[价格]字段进行Range搜索!
比如1200,2300,3450,这样的要能用1000-2000的范围搜到!
同时产品经理很倔,非要这个需求
没办法,想过用子表为主表,但是父表字段是子表的10倍,冗余的数据太多;想过先查一遍子表,再取出所有父表id作为查询条件,这种强行做关联的万一要查很大范围的价格,就崩了;还想过用父子索引,但是相关文档又少,感觉就不是es主推的东西.
最后,有个大佬终于找到方案,需要在多个数字搜索的时候,用数字数组,Range搜索到任何一个,就能命中.
直呼666后,剩下的就是Logstash的配置
把逗号分隔字段切分数组很简单
split => ["price", ","]
出现的问题也很简单,字符串切分了还是字符串
最后找了半天,在https://stackoverflow.com/questions/41400364/logstash-convert-array-of-objects-into-array-of-terms找到了用Ruby做类型转换的,感觉靠谱
自己查了下ruby语法,最后写好转换数组的脚本
ruby {
code => "event.set('price', event.get('price').map{ |n| n=n.to_i })"
}