距离+关键字搜索解决方案

时间:2012-07-23 22:48:31

标签: mysql search text properties geolocation

对于房地产网站,我需要实现一种搜索机制,允许搜索文本和距离 当 lat& amp;时,在 MySQL 表上进行距离计算。 lon 被记录在单独的列中很容易但是房子往往有{strong> LOT 的true/false属性。

我需要将所有这些字段存储在数据库中,因为它们需要可编辑,因此我打算使用像| houseID | property |这样的简单表,其中存储所有属性为true(set)的属性。

这将使我无法制作一个包含数百列的可笑宽表,但搜索此数据库将不太可行。

我考虑过为每个房子的主记录添加一个text类型的列,其中包含所有true属性的字段名。然后,我会搜索human文字说明和该文字列,但我觉得这仍然不是最佳方法。

我怎么能以干净的方式解决这个问题?

提前致谢!

1 个答案:

答案 0 :(得分:2)

我会推荐存储数据的Entity Attribute ValueEAV模型。 http://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model(这就是Wordpress Posts和Post Meta的工作方式)。

所以假设表格如下:

ENTITY_TABLE: (id,title,author,content,date_created,date_modified)
ATTRIBUTE_TABLE: (id, entity_id, akey, avalue)

使用如下查询:

SELECT e.*, 
    MAX( IF(m.akey= 'has_ac', m.avalue, 0) ) as 'has_ac', 
    MAX( IF(m.akey= 'has_garage', m.avalue, 0) ) as 'has_garage', 
    MAX( IF(m.akey= 'has_fridge', m.avalue, 0) ) as 'has_fridge', 
    MAX( IF(m.akey= 'latitude', m.avalue, 0) ) as 'latitude', 
    MAX( IF(m.akey= 'longitude', m.avalue, 0) ) as 'longitude'
FROM ENTITY_TABLE e
JOIN ATTRIBUTE_TABLE m ON e.id = m.entity_id
WHERE has_ac=1

将选择实体及其相关属性(has_ac,has_garage,has_fridge,纬度和经度),并要求所有选定的实体的has_ac等于1(true)

现在的地理位置:

SELECT e.*, 
    MAX( IF(m.akey= 'has_ac', m.avalue, 0) ) as 'has_ac', 
    MAX( IF(m.akey= 'has_garage', m.avalue, 0) ) as 'has_garage', 
    MAX( IF(m.akey= 'has_fridge', m.avalue, 0) ) as 'has_fridge', 
    MAX( IF(m.akey= 'latitude', m.avalue, 0) ) as 'latitude', 
    MAX( IF(m.akey= 'longitude', m.avalue, 0) ) as 'longitude',
    (
        3959 * 
        acos(
            cos( radians( MAX( IF(m.akey= 'latitude', m.avalue, 0) ) ) ) * 
            cos( radians( CUSTOMER_LAT ) ) * 
            cos( radians( CUSTOMER_LONG ) - radians( MAX( IF(m.akey= 'longitude', m.avalue, 0) ) ) ) + 
            sin( radians( MAX( IF(m.akey= 'latitude', m.avalue, 0) ) ) ) * 
            sin( radians( CUSTOMER_LAT ) ) 
        ) 
    ) AS distance
FROM ENTITY_TABLE e
JOIN ATTRIBUTE_TABLE m ON e.id = m.entity_id
WHERE has_ac=1
ORDER BY distance ASC