Elasticsearche 附近

使用Elasticsearch 真是遇到太多坑了。网上的一搜索抄袭太多,问题一个都解决不了。
后台通过实践,自己总算调通了。现在和后台的同志献上代码,希望大家别再走弯路。

第一步:
下载安装,部署elasticsearch 集群,不难,大家可以在网上搜索,给你们推荐慕课网,的“瓦力”,里面讲了如何部署和对接。

首先创建 索引:

新建索引
poistion 字段, type 是 geo_point
name 字段 type 是 text

put geo
put geo/geo/_mapping
{
  "properties": {
    "location": {
          "type": "geo_point"
           }
    }
}
put geo/geo/1
{
  "location": {
    "lat": 0.1,
    "lon": 0.1
  }
}
put geo/geo/2
{
  "location": {
    "lat": 50.1,
    "lon": 7.1
  }
}
put geo/geo/3
{
  "location": {
    "lat": 5.1,
    "lon": 3.1
  }
}
get geo/geo/_search
{
  "query": {
        "match_all": {
        }
    }, 
  "sort": [
       {
         "_geo_distance": {
           "location": {"lat":0, "lon":0}, 
           "order":"asc", 
           "unit":"km"
         }
       }
     ]
}

建立好后,就可以直接插入数据了。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
//get set 自己写, 我使用的是 lombok
public class EsShop implements Serializable {
    private Long id;
    private String title;
    private String name;
    private GeoPoint position;
    private String tag;
    private double distance;

数据操作


@Component
public class SearchService {

    @Autowired
    private JestClient jestClient;

    private static final String INDEX_NAME = "jack";
    /**
     * 表名
     */
    private static final String TABLE_NAME = "shop";
    /**
     * 搜索关键词的字段
     */
    private static final String FIELD_NAMES = "title,tag";

    public boolean addShop(EsShop shop) {
        Index.Builder builder = new Index.Builder(shop);
        Index index = builder.index(INDEX_NAME).type(TABLE_NAME).build();
        return executeBoolean(index);

    }


    public List<EsShop> getShop(String searchKey, Double lon, Double lat, int pageNumber, int pageSize) {
        Long nowTime = System.currentTimeMillis();

        SearchSourceBuilder builder = new SearchSourceBuilder();
        int start = (pageNumber - 1) * pageSize;

        MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(searchKey, FIELD_NAMES.split(","));
        builder.query(multiMatchQueryBuilder)
                .from(start)
                .size(pageSize);


        //获取距离多少公里 这个才是获取点与点之间的距离的
        GeoDistanceSortBuilder sortBuilder = new GeoDistanceSortBuilder("position", lat, lon);
        sortBuilder.unit(DistanceUnit.METERS);
        sortBuilder.order(SortOrder.ASC);
        sortBuilder.geoDistance(GeoDistance.ARC);


//        GeoDistanceSortBuilder sortBuilder = SortBuilders.geoDistanceSort("position", lat, lon)
//                .unit(DistanceUnit.METERS)
//                .order(SortOrder.ASC);

        builder.sort(sortBuilder);

        System.out.println(System.currentTimeMillis() - nowTime);

        Search search = new Search.Builder(builder.toString())
                .addIndex(INDEX_NAME)
                .addType(TABLE_NAME).build();
        try {
            JestResult ret = jestClient.execute(search);
            JsonObject jsonObject = ret.getJsonObject();
            EsJson esJson = JSON.parseObject(ret.getJsonString(), EsJson.class);
//            EsJson esJson = ret.getSourceAsObject(EsJson.class);
            List<EsJson.HitsBeanX.HitsBean> hits = esJson.getHits().getHits();
            List<EsShop> shopList = new ArrayList<>();
            for (int i = 0; i < hits.size(); i++) {
                EsShop shop = hits.get(i).get_source();
                shop.setDistance(hits.get(i).getSort().get(0));
                shopList.add(shop);
            }
            return shopList;
        } catch (IOException e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }


    public List<EsShop> getShop(String searchKey, int pageNumber, int pageSize) {
        SearchSourceBuilder builder = new SearchSourceBuilder();
        int start = (pageNumber - 1) * pageSize;

        MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(searchKey, FIELD_NAMES.split(","));
        builder.query(multiMatchQueryBuilder)
                .from(start)
                .size(pageSize);

        return execute(builder.toString());
    }

    public boolean deleteShop(Long shopId) {
        Delete delete = new Delete.Builder(shopId + "").index(INDEX_NAME).type(TABLE_NAME).refresh(true).build();
        return executeBoolean(delete);
    }


    private boolean executeBoolean(Action index) {
        try {
            JestResult result = jestClient.execute(index);
            return null != result && result.isSucceeded();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    private List<EsShop> execute(String sql) {
        Search search = new Search.Builder(sql)
                .addIndex(INDEX_NAME)
                .addType(TABLE_NAME).build();
        try {
            JestResult ret = jestClient.execute(search);
            List<EsShop> shopList = ret.getSourceAsObjectList(EsShop.class);
            return shopList;
        } catch (IOException e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

}

测试:

@Autowired
SearchService shopRepository;


@Test
public void test2() throws IOException {
    double lon = 100.123;
    double lat = 10.123;
    List<EsShop> b = shopRepository.getShop("西瓜", lon, lat, 1, 10);
    for (EsShop s : b) {
        System.out.println(s.toString());
    }
}

@Test
public void test() throws IOException {
    String[] sre = {"火锅", "串串", "回锅肉", "水煮肉", "西葫芦", "西瓜"};
    Random random = new Random();
    double lon = 100.000;
    double lat = 10.000;
    for (long i = 0; i < 10000; i++) {
        lon += 0.001;
        lat += 0.001;
        EsShop esShop = new EsShop();
        esShop.setId(i);
        esShop.setTitle(sre[random.nextInt(5)]);
        esShop.setPosition(new GeoPoint(lat, lon));
        esShop.setTag(sre[random.nextInt(5)] + "," + sre[random.nextInt(5)]);
        boolean b = shopRepository.addShop(esShop);
        System.out.println(b + "   " + esShop.toString());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值