# 开始搜索

# match 单字段搜索

//实例化引擎
$Wind = new \WindSearch\Index\Wind($indexName);

//开启分词功能
$Wind->loadAnalyzer();

//开始搜索

// 搜索单个字段
$query = [
    'match' => [
        'field' => [
            'name' => 'title',
            'query' => $text,
        ],
        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页

    ]

];

// 搜索接口
$res = $Wind->search($query, $page, $listRows);
// 返回的最终结果,可直接渲染到前台页面
$resArr = $res['result']['_source'];

# multi_match 多字段搜索

//实例化引擎
$Wind = new \WindSearch\Index\Wind($indexName);
//开启分词功能,搜索时,不需要加true
$Wind->loadAnalyzer();

// 搜索多个字段
$query = [
    'multi_match' => [
        'field' => [
            [
                'name' => 'title',
                'query' => $text,
            ],
            [
                'name' => 'tags',
                'query' => '蔬菜',// keyword字段无法分词
                
            ]

        ],
        'list_rows' => $listRows, // 每页多少条数据
        'page' => $page, // 第几页

    ]
];

// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# match_prefix 前缀匹配

// 前缀匹配
$query = [
    'match_prefix' => [
        'field' => [
            'name' => 'title',
            'query' => $text.'*',
        ],
       
        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页
    ],
];

// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# match_suffix 后缀匹配

// 后缀匹配
$query = [
    'match_suffix' => [
        'field' => [
            'name' => 'title',
            'query' => '*'.$text,
        ],
        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页
    ],
];

# match_prefix_suffix 前后缀混合匹配

// 前后缀匹配
$query = [
    'match_prefix_suffix' => [
        'field' => [
            'name' => 'title',
            'query' => ['关*','互联','*术'],// 参数支持:字符串、数组
            
        ],
       
        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页
    ],
];

# match_fuzzy 模糊搜索

//实例化引擎
$Wind = new \WindSearch\Index\Wind($indexName);
//开启分词功能,搜索时,不需要加true
$Wind->loadAnalyzer();

//开始搜索
$query = [
    'match_fuzzy' => [
        'field' => [
            'name' => 'title',
            'query' => $text,
        ],
        
        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页
    ]

];

// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# match_phrase 短语搜索

//实例化引擎
$Wind = new \WindSearch\Index\Wind($indexName);
//开启分词功能,搜索时,不需要加true
$Wind->loadAnalyzer();

//开始搜索
// 短语搜索 必须包含整个搜索query
// 如果搜索query包含停词,则很可能不会完整匹配出任何结果,因为term是被剔除过的
$query = [
    'match_phrase' => [
        'field' => [
            'name' => 'title',
            'query' => $text,
        ],
        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页
    ]

];

// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# match_terms 精确搜索

精确查询,设置的term不会被分词

// 精确查询
$query = [
    'match_terms' => [
        'field' => [
            'name' => 'tags',
            'terms' => ['蔬菜', '水果'],
            // 'terms' => '蔬菜',
        ],
        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页

    ]

];
// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# match_bool 布尔搜索

# bool搜索 无嵌套

// 布尔查询
$query = [
    'match_bool' => [
        'bool' => [
            //and
            'must' => [
                'match' => [
                    [
                    'title' => $text,
                    ],
                    // ['tags' => '服装',],

                ],

            ],
            //or
            'should' => [
                'match' => [
                    [
                        'area' => '中国',
                    ],
                    [
                        'area' => '韩国',
                    ],
                ],
                'minimum_should_match' => 1, //最少应该同时满足几个

            ],
            //必须不包含
            'must_not' => [
                'match' => [//字段间 or
                    ['level' => '三级',],
                    ['level' => '二级',],
                ],

            ],
            //筛选过滤
            'filter' => [
                'range' => [//可多个过滤字段
                    'score' => [ //每个字段一个或两个条件 lt lte gt gte
                        'lt' => 1000,
                        'gt' => 9,
                    ],
                    'time' => [
                        'lt' => 1710288994
                    ],
                ],
            ],
        ],
        // 只对must下面的字段有效
        'highlight' => [
            'is_cut' => true, // 是否将未匹配的地方截取掉
            'fixed_length' => '', //保留多少字符,若为空,则保持原长度
        ],
        // 结果排序
        'sort' => [
             'time' => 'desc' //asc 按字段值正序 desc 按字段值倒序
        ],
        '_source'=>['id','title','descr'],//返回自定义字段,为空则全部返回
        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页
    ],
];

// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# bool搜索 should嵌套

// 布尔搜索 嵌套
$query = [
    'match_bool' => [
        'bool' => [
            //and
            'must' => [
                'match' => [
                    [
                        'title' => $text,
                    ],
                    // ['tags' => '服装',],

                ],

            ],
            //or should嵌套
            'should' => [
                [
                    'bool' => [
                        'should' => [
                            'match' => [
                                [
                                    'area' => '中国',
                                ],
                                [
                                    'area' => '韩国',
                                ],
                            ],
                            'minimum_should_match' => 1, //最少应该同时满足几个
                        ],

                    ]
                ],
                [
                    'bool' => [
                        'should' => [
                            'match' => [
                                [
                                    'area' => '美国',
                                ],
                                [
                                    'area' => '新加坡',
                                ],
                            ],
                            'minimum_should_match' => 1, //最少应该同时满足几个
                        ],
                      

                    ]
                ],
                'minimum_should_match' => 1, //最少应该同时满足几个

            ],
            //必须不包含
            'must_not' => [
                'match' => [
                    ['level' => '三级',],
                ],

            ],
            //筛选过滤
            'filter' => [
                'range' => [
                    'score' => [
                        'lt' => 45,
                        'gt' => 9,
                    ],
                    'time' => [
                        'lt' => 1710288994
                    ],
                ],
            ],
        ],
        'highlight' => [
            'is_cut' => true, // 是否将未匹配的地方截取掉
            'fixed_length' => '', //保留多少字符,若为空,则保持原长度
        ],
        // 结果排序
        'sort' => [
            'time' => 'desc' //asc 按字段值正序 desc 按字段值倒序
        ],
        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页
    ],
];

// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# match_range 范围查询

// 范围查询
$query = [
    'match_range' => [ //lt lte gt gte
        'range' => [
            'score' => [
                'gt' => 9,
                'lt' => 40,
            ],
            'time' => [
                'gt' => 1684206252
            ],
        ],
        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页
    ],
];

// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# match_all 查询所有数据

// 查询所有数据
$query = [
    'match_all' => [
        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页
        'order' => 'asc', //desc 倒序 asc 正序
    ],
];

// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# match_rand 随机获取数据

// 随机获取数据
$query = [
    'match_rand' => [
        'size' => 10, //int 随机返回指定数量的结果
    ],
];

// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# match_primarykey 根据主键查询数据

// 根据主键查询数据
$query = [
    'match_primarykey'=>[
        'primarykey'=>'5,4,3,2',//array or string
    ],
];

// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# match_geo 地理空间搜索

//实例化引擎
$Wind = new \WindSearch\Index\Wind($indexName);

// 地理空间搜索
$query = [
    'match_geo' => [
        'field' => [
            'name' => 'location', // 要进行搜索的字段,类型必须为geo_point
            'geo_point' => [
                'lat' => '30.621900130545825', //纬度
                'lon' => '114.28891807367313', //经度
            ],
            // 'distance' => '10000m', // 10公里范围内
            'distance' => ['10km', '20km'], // 1公里到10公里范围内
        ],
        // 结果排序
        'sort' => [
            'geo_distance' => 'asc' //asc 按距离升序 desc 按距离降序
        ],
        '_source' => ['title', 'descr'],//自定义返回字段
        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页
    ]
];

// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# match_auto_completion 搜索建议

// 配置搜索建议
// 在配置mapping时,在需要用于搜索建议的字段上,做如下配置:
 [
    'name' => 'title',
    'type' => 'text', //数据类型:文本类型,会根据analyzer配置的方式进行分词
    'index' => true, // 会被索引
     
    'function' => [ //功能
        'completion' => [], //自动补全(搜索建议)
    ]
],


//进行搜索建议、自动补全
$Wind = new \WindSearch\Index\Wind($indexName);
$query = [
    'match_auto_completion' => [
        'field' => [
            'name' => 'title',//title字段必须配置为completion
            'query' => $text,
        ],
        'num' => 10, //返回多少条数据
    ]

];
// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可重构数据结构,返回前台用于搜索提示
// ...

# 敏感词检测

引擎内置了trie树算法,可快速构建敏感词前缀索引,高效地进行敏感词检测

# 导入敏感词数据

//导入敏感词数据,构建trie树索引
$Wind = new \WindSearch\Index\Wind();
// 将敏感词数据导入,引擎会自动构建索引,并自动保存
// 内部会自动删除字符串中所有空格
// $arr = ['敏感词1','敏感词2','敏感词3'...]
$Wind->buildSensitiveIndex($arr);

# 检测是否存在敏感词

// 只检测是否存在敏感词
$Wind = new \WindSearch\Index\Wind();
$isSensitive = $Wind->checkSensitive('需要检测的字符串');
// 存在敏感词,返回true
if($isSensitive){
    echo '存在敏感词';
}
// 不存在返回false
else{
    echo '不存在敏感词';
}

# 替换掉所有敏感词

// 检测并替换所有存在的敏感词
$Wind = new \WindSearch\Index\Wind();
$replace = '***';//替换字符,可选,默认值为 **
// 开始检测替换
$replaceRes = $Wind->checkSensitiveReplace('需要检测的字符串',$replace);
// $replaceRes为替换结果

# 提取所有敏感词

// 提取所有敏感词
$Wind = new \WindSearch\Index\Wind();
$allSensitiveWords = $Wind->getAllSensitiveWords('需要检测的字符串');
// $allSensitiveWords为被检测字符串内所有的敏感词

# aggs 聚合查询

聚合查询性能很差,数据量大时慎用

# 分组聚合(基础)

//实例化引擎
$Wind = new \WindSearch\Index\Wind($indexName);

// 分组聚合 以某个字段的内容进行分组,默认统计每组的总数 count
$query = [
    'aggs_group_simp' => [
        'field' => [
            'name' => 'area', // 以area字段内容进行分组
            'match' => [ //限制字段的内容
                'tags' => ['蔬菜', '水果', '饮料', '零食'], //值可以为字符串,也可以为数组; 限制字段,如果是keyword类型,会走索引,否则会全表扫描
                'area'=>'中国',
            ],
        ],
        'sort' => [
            '_count' => 'desc'
        ],
        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页
    ],
];

// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# 分组聚合(进阶)

//实例化引擎
$Wind = new \WindSearch\Index\Wind($indexName);

// 分组聚合 进阶
$query = [
    'aggs_group' => [
        'field' => [
            'name' => 'tags', // 以time字段内容进行分组
            'match' => [ //可选 限制字段的内容
                'area' => ['中国'], //分组字段必须是keyword类型;限制字段,如果是keyword类型,会走索引,否则会全表扫描
            ],
        ],
        'sum'=>[
            'avg' => [
                'name' => 'score' // 分组后,再计算每组的score的平均值,再获取平均值最大的那一条 avg max min sum
            ],
        ],

        'list_rows' => $listRows, //每页多少条数据
        'page' => $page, //第几页
    ],
];
// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# 指标聚合

//实例化引擎
$Wind = new \WindSearch\Index\Wind($indexName);

// 指标聚合 max min avg sum
$query = [
    'aggs_metrics' => [
        'max' => [
            'field' => [
                'name' => 'price', // 最大值
            ],
        ],
        'min' => [
            'field' => [
                'name' => 'price', // 最小值
            ],
        ],
        'avg' => [
            'field' => [
                'name' => 'price', // 平均值
            ],
        ],
        'sum' => [
            'field' => [
                'name' => 'price', // 总和
            ],
        ],

    ],
];


// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...

# 分组嵌套

//实例化引擎
$Wind = new \WindSearch\Index\Wind($indexName);
// 嵌套查询
$query = [
    'aggs_group' => [
        'field' => [
            'name' => 'tags', // 以tags字段内容进行分组 分组字段必须是keyword类型
            'match' => [ //可选 限制字段的内容,字段必须是keyword类型
                'area' => ['中国'], // 只查询聚合area为“中国”的内容
            ],
        ],
        'aggs_group' => [
            'field' => [
                'name' => 'level', // 再在tags字段分组的基础上,以level字段内容进行分组
            ],
            'max' => [
                'avg' => [
                    'name' => 'score' // 分组后,再计算每组的score的平均值,再获取平均值的最大值 avg max min sum
                ],
            ],
        ],
        'list_rows' => $listRows, //每页多少条数据
		'page' => $page, //第几页
    ],
];
// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果
// ...