2016-06-16 10 views
0

私は、elasticsearchにairbnbタイプのアパートメントを数百万個保存する予定です。 availabiltyは、nestedオブジェクト(availabilityタイプはnested)を含む配列です。 これらのオブジェクトのそれぞれは、そのアパートメントが利用可能な日付範囲を持っています。ElasticSearch - 日付範囲の条件が日付範囲の配列の1つの項目と正確に一致する必要があります

apartments = [ 
    { 
    "_id": "kjty873yhekrg789e7r0n87e", 
    "first_available_date": "2016-06-21", 
    "availability": [ 
     { 
     "start": "2016-06-21", 
     "end": "2016-08-01" 
     }, 
     { 
     "start": "2016-08-20", 
     "end": "2016-08-28" 
     }, 
     { 
     "start": "2016-10-03", 
     "end": "2016-11-02" 
     }, 
     { //This means it is available only for one day. 
     "start": "2016-11-13", 
     "end": "2016-11-13" 
     }, 
     { 
     "start": "2016-11-28", 
     "end": "2017-01-14" 
     } 
    ], 
    "apartment_metadata1": 56456, 
    "apartment_metadata2": 8989, 
    "status": "active" 
    }, 
    { 
    "_id": "hgk87783iii86937jh", 
    "first_available_date": "2016-06-09", 
    "availability": [ 
     { 
     "start": "2016-06-09", 
     "end": "2016-07-02" 
     }, 
     { 
     "start": "2016-07-21", 
     "end": "2016-12-19" 
     }, 
     { 
     "start": "2016-12-12", 
     "end": "2017-07-02" 
     } 
    ], 
    "apartment_metadata1": 23534, 
    "apartment_metadata2": 24377, 
    "status": "active" 
    } 
] 

特定の期間(たとえば、2016-08-20 to 2016-12-12)で利用可能なアパートメントを検索したいと考えています。そして、 の範囲は、様々なアパートメントの利用可能な日付範囲の1つに該当するはずです。私は、クエリを書きたい

だから、のようなもの:

{ 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "range": { "first_available_date": {"lte": "2016-08-20"} }, 
      "match": { "status": "active" } 
     } 
     ] 
     }, 
     "filter": [ 
     { 
      "range": 
      { 
       "apartments.availability.start": {"gte": "2016-08-20"}, 
       "apartments.availability.end": {"lte": "2016-12-12"} 
      } 
     } 
    ] 
    } 
    } 
} 

とQuery上記は、私に(条件に一致する複数のavailabilityオブジェクトとの)両方のアパートメントを返し 、それは間違っているだろう、それだけ返す必要があります_id: hgk87783iii86937jhと書かれています。正確に1つのavailabilityオブジェクトがクリエイティブと一致し、それは{"start": "2016-07-21", "end": "2016-12-19"}です。だから、正しい結果を得るためには、条件が一致するはずのアパートののアパートに、ただ1つのavailabilityオブジェクトがあるはずです。それで、上記のクエリには正確に1つの一致が存在するように強制する方法は? 2番目の質問 - 私の質問は正しいですか?

+0

https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-mapping([ネストされた] availability' 'のためのマッピングは型であることを確認してください.html)、次に[ネストされたクエリ](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html)を使用して達成できるはずです – keety

+0

@keetyはい、ポストでも述べたように私は持っています。しかし、私の質問は、どのようにして、ただ一つの可用性オブジェクトが条件にマッチするドキュメントだけを得るのですか? – JVK

+0

あなたは 'availbitly object'が上記の条件を満たす例を挙げることができますか? – keety

答えて

1

nested queryを使用すると、上記を達成する必要があります。 inner-hitsを使用して一致するavailability-blockを取得してください。以下 はこれを実装する例である:

インデックス

put testindex 
{ 
    "mappings": { 
     "data" : { 
      "properties": { 
       "availability" : { 
        "type": "nested" 
       } 
      } 
     } 
    } 
} 

インデックスデータ作成:

put testindex/data/1 
{ 

    "first_available_date": "2016-06-21", 
    "availability": [ 
    { 
     "start": "2016-06-21", 
     "end": "2016-08-01" 
    }, 
    { 
     "start": "2016-08-20", 
     "end": "2016-08-28" 
    }, 
    { 
     "start": "2016-10-03", 
     "end": "2016-11-02" 
    }, 
    { 
     "start": "2016-11-13", 
     "end": "2016-11-13" 
    }, 
    { 
     "start": "2016-11-28", 
     "end": "2017-01-14" 
    }, 
    { 
     "start": "2016-07-21", 
     "end": "2016-12-19" 
     } 
    ], 
    "apartment_metadata1": 4234, 
    "apartment_metadata2": 687878, 
    "status": "active" 
} 

問合せ:

post testindex/data/_search 
{ 
    "query": { 
     "bool": { 
     "must": [ 
      { 
       "range": { 
        "first_available_date": { 
        "lte": "2016-08-20" 
        } 
       } 
      }, 
      { 
       "match": { 
        "status": "active" 
       } 
      } 
     ], 
     "filter": [ 
      { 
       "nested": { 
        "path": "availability", 
        "query": { 
        "bool": { 
         "must": [ 
          { 
           "range": { 
           "availability.start": { 
            "lte": "2016-08-20" 
           } 
           } 
          }, 
          { 
           "range": { 
           "availability.end": { 
            "gte": "2016-12-12" 
           } 
           } 
          } 
         ] 
        } 
        }, 
        "inner_hits": {} 
       } 
      } 
     ] 
     } 
    } 
} 

結果:

"hits": { 
     "total": 1, 
     "max_score": 1.4142135, 
     "hits": [ 
     { 
      "_index": "testindex", 
      "_type": "data", 
      "_id": "1", 
      "_score": 1.4142135, 
      "_source": { 
       "first_available_date": "2016-06-21", 
       "availability": [ 
        { 
        "start": "2016-06-21", 
        "end": "2016-08-01" 
        }, 
        { 
        "start": "2016-08-20", 
        "end": "2016-08-28" 
        }, 
        { 
        "start": "2016-10-03", 
        "end": "2016-11-02" 
        }, 
        { 
        "start": "2016-11-13", 
        "end": "2016-11-13" 
        }, 
        { 
        "start": "2016-11-28", 
        "end": "2017-01-14" 
        }, 
        { 
        "start": "2016-07-21", 
        "end": "2016-12-19" 
        } 
       ], 
       "apartment_metadata1": 4234, 
       "apartment_metadata2": 687878, 
       "status": "active" 
      }, 
      "inner_hits": { 
       "availability": { 
        "hits": { 
        "total": 1, 
        "max_score": 1.4142135, 
        "hits": [ 
         { 
          "_index": "testindex", 
          "_type": "data", 
          "_id": "1", 
          "_nested": { 
           "field": "availability", 
           "offset": 5 
          }, 
          "_score": 1.4142135, 
          "_source": { 
           "start": "2016-07-21", 
           "end": "2016-12-19" 
          } 
         } 
        ] 
        } 
       } 
      } 
     } 
     ] 
    } 
+0

ありがとうございました。私の質問 - "inner_hits"を使用すると、検索条件に一致する複数のヒットオブジェクトが返される可能性があります。または常に1つのオブジェクトを返しますか?それが複数のものを返すことができるなら、それは私を助けるつもりではない。 – JVK

+0

私はあなたの解決策をupvotingです:) – JVK

+0

upvote、私はちょうど文書が複数のavailabiltiyオブジェクトを持つことが可能ですか?上記のクエリが複数のオブジェクトを返す例を挙げることができますか? – keety