---
title: "Solr空間探索の利用"
slug: "using-solr-spatial-search"
abstract: "空間探索を使って、さまざまな方法で地理的なポイントを検索できます"
---
# Solr空間探索の利用

> !注このトピックはSitecore 9.0以降にも適用されます。

SitecoreのSolr空間検索機能の一部を利用できます。空間探索は以下の通りです:

-   インデックスポイントをSearch(Latitude, Longitudeの形式を使用)
-   サークルやバウンディングボックスに基づいて検索結果をフィルタリングします
-   ポイント間の距離でスコアを並べ替えたり強化したりできます

Sitecoreインデックス作成および検索のためにSolrのSpatialRecursivePrefixTreeFieldTypeタイプ(略してRPT)をサポートしています。マスターデータベースにはインデックスポイントを保存するためのCoordinate Sitecoreテンプレートが */sitecore/templates/System/Geospatial/* 存在します。 Coordinateテンプレートには2つのフィールドがあります – LatitudeとLongitude。このテンプレートからアイテムを作成すると、座標はSolrでインデックスされます。

## 使用方法

この例コードは、Sitecore LINQクエリを使ってクアラルンプール市中心部から半径10キロメートル以内のポイントのリストを検索し、座標は3.156230および101.713614であることを示しています:

context.GetQueryable < SearchResultItem > ()
 .WithinRadius(s => s.Location, new Coordinate(3.156230, 101.713614), 10)
## WithinRadius API

このAPIには3つのパラメータがあります:

1.  点の座標を含むプロパティです。このプロパティをIndexField("coordinate") マークし、Coordinateクラスを返さなければなりません。
    
    例えば:
    
    /// <summary>Gets or sets the coordinate of POI.</summary>
    
    IndexField("coordinate")
    
    DataMember
    
    public Coordinate Location { get; set; }
    
2.  一定距離内の他の点を探す際に使用する中心点の座標。
    
3.  指定された中心点座標から一定距離内にある任意の点を探すために使われる半径。
    

4つ目のオプションパラメータがあります。それを使って、Solrが円の中ではなく境界ボックス内の点を探すかどうかを指定します。

SitecoreのLINQクエリ順を使って、上順(デフォルト)または降下距離のいずれかで並べたポイントを返すことができます:

var queryable = context.GetQueryable < SearchResultItem > ()
 .OrderByDistance(s => s.Location, "3.156230, 101.713614");
var queryable = context.GetQueryable < SearchResultItem > ()
 .OrderByDistanceDescending(s => s.Location, "3.156230, 101.713614");

WithinRadius APIとOrderByDistance API、またはOrderByDistanceDescending APIを組み合わせることで、指定された半径内に位置する点のリストを取得することができます。結果は中心点への近さの上昇または下降順に並べられており、この例のように以下の通りです。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WithinRadius.aspx.cs" Inherits="Sitecore.ContentSearch.SolrProvider.Example.WithinRadius" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
 <title></title>
</head>
<body>
 <form id="form1" runat="server">
 <div>
 </div>
 </form>
</body>
</html>

WithinRadius.aspx.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Sitecore.ContentSearch.Data;
using Sitecore.ContentSearch.Linq;
using Sitecore.ContentSearch.SearchTypes;
namespace Sitecore.ContentSearch.SolrProvider.Example {
 public partial class WithinRadius : System.Web.UI.Page {
 protected void Page\_Load (object sender, EventArgs e) {
 var index = ContentSearchManager.GetIndex ("sitecore\_master\_index");
 var htmlBuilder = new StringBuilder ();
 using (var context = index.CreateSearchContext ()) {
 var queryable = context.GetQueryable<SearchResultItem> ()
 .WithinRadius (s => s.Location, new Coordinate (3.156230, 101.713614), 10)
 //.OrderByDistanceDescending(s => s.Location, "3.156230, 101.713614");
 .OrderByDistance (s => s.Location, "3.156230, 101.713614");
 var list = queryable.ToList ();
 if (list.Count == 0) {
 Response.Write ("<div style='color:red'>No POI within the radius</div>");
 return;
 }
 htmlBuilder.AppendFormat ("Found {0} item within vicinity. <br/>", list.Count);
 htmlBuilder.Append ("<div><ul>");
 foreach (var item in list) {
 htmlBuilder.AppendFormat ("<li>{0} : {1}</li>", item.Name, item.Location.ToString ());
 }
 htmlBuilder.Append ("</ul></div>");
 Response.Write (htmlBuilder);
 }
 }
 }
}