CouchDB全文搜索查询
前言
couchdb的geo查询并不能结合其他搜索,所以会有局限性,如果想要多条件的查询,这种方法是行不通的,有一种有局限性的,就是通过全文搜索查询点的KNN?从这篇文章获得的方法。
couchdb自带并不支持全文搜索查询,支持lucene,需要安装clouseau,但是自带Dreyfus,这个就不需要安装了。这之间的关系非常乱,一开始没搞懂,后来摸清楚了,先捋一下这之间的关系。
首先lucene是apache基金下的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,如果couchdb需要使用,需要使用clouseau,clouseau的作用就是暴露lucene的特性给erlang RPC协议,因为CouchDB使用erlang写的)。然后couchdb想要使用clouseau的接口,需要安装dreyfus,这个主要的作用就是管理clouseau节点来传递全文搜索的特征。简单来说,就是dreyfus处理传递需要全文搜索的语句给clouseau,然后clouseau通过lucene查询全文搜索的语句,返回回去。
安装使用
在couchdb2.x版本,还需要单独安装dreyfus,但是3.1.1里面集成了,不用单独再安装了,Couchdb更新文档里面有说明。
#2037: Dreyfus, the CouchDB side of the Lucene-powered search solution, is now shipped with CouchDB. When one or more Clouseau Java nodes are joined to the cluster, text-based indexes can be enabled in CouchDB. It is recommended to have as many Clouseau nodes as you have CouchDB nodes. Search is advertised in the feature list present at
GET /if configured correctly (#2206). Configuration and installation documentation is available.
所以只需要安装clouseau,具体安装过程参考这三篇,第一个是couchdb文档search plugin installation,第二个查询服务的配置,第三个couchdb-docker里面的实例使用clouseau,非常的有用。本仓库也直接提供了使用方法,在search_clouseau里面,例子和官方的一样。通过下面的语句就能启动了。
docker-compose -f docker-compose-offical.yaml up -d
然后使用该目录下的searchOfGeo.sh文件,里面的使用方法是参考官方的搜索文档
./offical_searchOfGeo.sh
就能成功看到返回排序好的地理结果。
{"total_rows":2,"bookmark":"g1AAAABFeJzLYWBgYMxgTmEQTc4vTc5ISXKA0gZ6JanFJTlAaaY8FiDJ0ACk_gNBFljMzeHyxISODYZ7ExmzsgCoGxWs","rows":[{"id":"e9f5afbc8c6ec5f1ad51dbc9b4000758","order":[20037.508342789242,0],"fields":{"city":"Aberdeen, Scotland","lat":[-2.15,56.15]}},{"id":"e9f5afbc8c6ec5f1ad51dbc9b4000ce3","order":[20037.508342789242,1],"fields":{"city":"Aberdeen, Scotland","lat":[-2.15,55.15]}}]}
注意:有时候docker-compose的命令会被挂起,并且是永久性的,不知道是什么问题,我参考了这个解答,发现能用,通过下面这个命令查看自己的系统熵?
cat /proc/sys/kernel/random/entropy_avail
我的并非是虚拟系统(应该),但我的熵确实小于1000,只有10左右,所以就导致docker-compose不能正常运行,我其中的某些命令一下子会用掉上百个熵,所以需要增加熵。只需要安装haveged,即始终保持这个熵在一千以上,完美解决。
sudo apt-get install haveged
ps -ef | grep "haveged" | grep -v "grep"
CouchDB集群使用
普通JSON格式
也一样,集群使用的docker-compose-cluster.yml文件,有三个couchdb成一个集群,每一个集群都有一个clousea。这里面的CouchDB并非官方的couchdb,而是我在官方CouchDB3.1.1上集成了hastings和easton支持空间搜索的CouchDB。
docker-compose -f docker-compose-cluster.yml up -d
然后建立集群,需要sleep 2秒,不知道为什么curl过快,最后一句完成集群就会有问题,所以建议还是每一句加一个延时。
./cluster.sh
使用,这是官方示例的搜索。
./offical_searchOfGeo.sh
offical_searchOfGeo.sh文件内容。
# 创建表
curl -X PUT admin:adminpw@localhost:5984/city
sleep 1
# 创建搜索索引,具体创建格式参考官方文档:https://docs.couchdb.org/en/3.1.1/ddocs/search.html#ddoc-search
curl -X POST -H "Content-Type: application/json" -d '
{
"_id": "_design/trymesoft",
"indexes" : {
"shelter_search": {
"index" : "function(doc) { if(doc.type && doc.type=='"'city'"') { index('"'city'"',doc.name,{'"'store'"':true}); index('"'lat'"',doc.lat,{'"'store'"':true}); index('"'lon'"',doc.lon,{'"'store'"':true}); } }"
}
}
}' admin:adminpw@localhost:5984/city
sleep 1
# 添加数据
curl -X POST -H "Content-Type: application/json" -d '
{
"name":"Aberdeen, Scotland",
"lat":56.15,
"lon":-2.15,
"type":"city"
}
' admin:adminpw@localhost:5984/city
sleep 1
curl -X POST -H "Content-Type: application/json" -d '
{
"name":"Aberdeen, Scotland",
"lat":55.15,
"lon":-2.15,
"type":"city"
}
' admin:adminpw@localhost:5984/city
sleep 1
# 查询空间属性,具体使用方法查看 https://docs.couchdb.org/en/3.1.1/ddocs/search.html#ddoc-search-geographical-searches
curl -X POST -H "Content-Type: application/json" -d '
{
"q":"*:*",
"sort":"<distance,lon,lat,-2.15,57.15,km>"
}' admin:adminpw@localhost:5984/city/_design/trymesoft/_search/shelter_search
GeoJSON
但如果想结合hastings和easton的空间搜索,需要使用GeoJSON,那么结构大体上是这样子的。
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-71.13687953, 42.34690635]
},
"properties": {
"name": "1"
}
}
所以如果想要既能够使用GeoSpatial查询和全文搜索,需要使用GeoJSON,并且全文搜索建立的索引的方式也要改变,对type为Point类型的数组中的lat和lon进行索引。搜索索引格式如下。
function(doc) {
if (doc.type && doc.geometry.type == 'Point') {
index('lon', doc.geometry.coordinates[0], {'store': true});
index('lat', doc.geometry.coordinates[1], {'store': true});
}
}
可以使用geojson_searchOfGeo.sh文件来查看效果。
###
# @Author: szx
# @Date: 2021-12-12 14:34:28
# @LastEditTime: 2021-12-12 16:29:01
# @Description:
# @FilePath: /couchdb-hastings-3.1.1/search_clouseau/geojson_searchOfGeo.sh
###
# 创建表
curl -X PUT admin:adminpw@localhost:5984/city
sleep 1
# 创建搜索索引,具体创建格式参考官方文档:https://docs.couchdb.org/en/3.1.1/ddocs/search.html#ddoc-search
# 这里索引则是geojson.geometry.coordinates的两个数组进行索引
curl -X POST -H "Content-Type: application/json" -d '
{
"_id": "_design/trymesoft",
"indexes" : {
"shelter_search": {
"index" : "function(doc) { if(doc.type && doc.geometry.type=='"'Point'"') { index('"'lon'"',doc.geometry.coordinates[0],{'"'store'"':true}); index('"'lat'"',doc.geometry.coordinates[1],{'"'store'"':true}); } }"
}
}
}' admin:adminpw@localhost:5984/city
sleep 1
# 创建地理空间索引
curl -X POST -H "Content-Type: application/json" -d '
{
"_id": "_design/SpatialView",
"st_indexes" : {
"shelter_positions": {
"index" : "function(doc) { if (doc.geometry) { st_index(doc.geometry); } }"
}
}
}' admin:adminpw@localhost:5984/city
sleep 1
# 添加数据
curl -X POST -H "Content-Type: application/json" -d '
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [59.123, 18.123]
},
"properties": {
"name": "1"
}
}
' admin:adminpw@localhost:5984/city
sleep 1
curl -X POST -H "Content-Type: application/json" -d '
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [58.789, 17.789]
},
"properties": {
"name": "2"
}
}
' admin:adminpw@localhost:5984/city
sleep 1
# 添加一个polygon
curl -X POST -H "Content-Type: application/json" -d '
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[[58.889,17.889],[58.989,17.889],[58.989,17.989],[58.889,17.889]]]
},
"properties": {
"name": "3"
}
}
' admin:adminpw@localhost:5984/city
sleep 1
# 地理空间查询圆内的图形,包括polygon
echo 'GeoSpatial result:'
curl -X GET "admin:adminpw@localhost:5984/city/_design/SpatialView/_geo/shelter_positions?lat=18&lon=59&radius=100000&relation=contains&format=geojson"
sleep 1
# 查询空间属性,具体使用方法查看 https://docs.couchdb.org/en/3.1.1/ddocs/search.html#ddoc-search-geographical-searches
echo 'Search result:'
curl -X POST -H "Content-Type: application/json" -d '
{
"q":"*:*",
"sort":"<distance,lon,lat,59,18,km>"
}' admin:adminpw@localhost:5984/city/_design/trymesoft/_search/shelter_search



