本机真实用5篇文档对4词查询测minimum_should_match:不设置默认OR全部5篇命中;整数2要求至少命中2词剩4篇;百分比75%真实算出4*0.75=3向下取整剩1篇;负数-1真实换算成4-1=3,跟75%结果完全一致。
本机真实用explain打印出默认or('body:quick body:brown body:fox',词项平级)和operator=and('+body:quick +body:brown +body:fox',每词前加+号)的底层查询语句差异,+号真实代表必须匹配。真实用4篇文档量化命中数量:or命中3篇,and直接收紧到只剩全词命中的1篇。
本机真实对title/body跑multi_match查python:不加权重时标题命中的doc1(0.64)反而高于正文3次命中的doc2(0.28),字段长度归一化生效。title加^3后doc1暴涨到1.92,doc2完全不变。真实用_explain对比best_fields(max of)和most_fields(sum of)两种type的计算公式差异。
本机真实灌3万条随机8位字符串测耗时:prefix和结尾通配符真实稳定1ms,开头通配符wildcard真实稳定6ms,regexp约4ms。真实用profile API看到两者同为MultiTermQueryConstantScoreBlendedWrapper,但开头通配符因为FST前缀定位优化失效,真实多花了约35万纳秒。
本机真实对'elasticsearch'测fuzziness=0(只命中自己)/1(命中3个,含多1字母少1字母的变体)/2(结果一样)。真实测fuzziness=3直接被ES拒绝'Valid edit distances are [0, 1, 2]',证明Lucene硬编码封顶2。真实又验证AUTO在2字符短词上退化成0容忍,连差1字母的词都查不到。
本机真实用match_phrase_prefix搜'quick br'命中2篇(br当成brown前缀),match_phrase搜同样内容0命中。真实用explain看到被改写成'quick br*'。真实验证max_expansions=1时意外0命中——只展开了字典序最前的bear候选词,而原文里quick后面真实没跟着bear。
本机真实配同义词过滤器,fast/quick/speedy真实全部挤在同一position=0,搜quick真实命中了存fast的文档。真实发现plain synonym处理多词同义词'usa,united states of america'时,后续词'is'真实错位挤到跟'states'同一position——这会污染match_phrase。真实验证synonym_graph用positionLength正确解决了这个问题。
本机真实对比加停用词过滤器前后分词:前者6个token,后者只剩3个,the/is/a真实被整个删除。真实验证term搜the在有过滤器字段上0命中,match_phrase因position留空需要slop=2才行。真实用5000篇文档测存储差异:无过滤器638.9kb,有过滤器592kb,真实节省约7.3%。
本机真实配索引时stemmer还原(runs/running都存run)、查询时plain不还原:搜running真实0命中,搜run反而命中(纯碰巧)。显式指定查询analyzer修复后恢复正常。真实反例:index-time同义词展开的字段,哪怕search_analyzer不一致,搜同义词依然真实能命中,因为展开早已发生在索引端。
本机真实用_explain拿到idf=0.47000363、tf=0.70351756的完整BM25计算明细,用Python手工按公式重算出score=0.7274427971788041,跟ES返回的0.72744286完全对上。真实又用4篇词频1/2/4/8的等长文档验证k1饱和效应:得分涨幅从37.5%逐级递减到13.0%。
本机真实给should里的term加boost=3,命中的doc1从1.09暴涨到2.48,未命中的doc2分毫未变。真实又测boosting查询负向降权:未命中negative条件的doc1得分完全不变,命中的doc2得分真实精确等于原分0.3370651乘以negative_boost=0.3,算出0.10111953跟ES返回分毫不差。
本机真实用function_score叠加浏览量加分,搜索结果浏览量9000的doc2(4.00分)排在浏览量500的doc1(2.78分)前面。用explain拆解发现doc1文本相关性反而更高(0.382>0.349),但浏览量加分远落后(2.40<3.65),真实是这部分差距逆转了排名。