List<Person> findByAddressZipCode(ZipCode zipCode);
這裏假設各位已經簡單瞭解過elasticsearch,並不對es進入更多的,更深層次的解釋,若有必要,會在寫文章專門進行es講解。html
Elasticsearch是一個基於Apache Lucene(TM)的開源搜索引擎。不管在開源仍是專有領域,Lucene能夠被認爲是迄今爲止最早進、性能最好的、功能最全的搜索引擎庫。java
可是,Lucene只是一個庫。想要使用它,你必須使用Java來做爲開發語言並將其直接集成到你的應用中,更糟糕的是,Lucene很是複雜,你須要深刻了解檢索的相關知識來理解它是如何工做的。node
Elasticsearch也使用Java開發並使用Lucene做爲其核心來實現全部索引和搜索的功能,可是它的目的是經過簡單的RESTful API
來隱藏Lucene的複雜性,從而讓全文搜索變得簡單。mysql
index ==》索引 ==》Mysql中的一個庫,庫裏面能夠創建不少表,存儲不一樣類型的數據,而表在ES中就是type。git
type ==》類型 ==》至關於Mysql中的一張表,存儲json類型的數據github
document ==》文檔 ==》一個文檔至關於Mysql一行的數據算法
field ==》列 ==》至關於mysql中的列,也就是一個屬性spring
這裏多說下:sql
在Elasticsearch6.0.0或者或者更新版本中建立的索引只會包含一個映射類型(mappingtype)。在5.x中建立的具備多個映射類型的索引在Elasticsearch6.x中依然會正常工做。在Elasticsearch7.0.0中,映射類型type將會被徹底移除。數據庫
開始的時候,咱們說「索引(index)」相似於SQL數據庫中的「數據庫」,將「類型(type)」等同於「表」。
這是一個糟糕的類比,而且致使了一些錯誤的假設。在SQL數據庫中,表之間是相互獨立的。一個表中的各列並不會影響到其它表中的同名的列。而在映射類型(mappingtype)中卻不是這樣的。
在同一個Elasticsearch索引中,其中不一樣映射類型中的同名字段在內部是由同一個Lucene字段來支持的。換句話說,使用上面的例子,user類型中的user_name字段與tweet類型中的user_name字段是徹底同樣的,而且兩個user_name字段在兩個類型中必須具備相同的映射(定義)。
這會在某些狀況下致使一些混亂,好比,在同一個索引中,當你想在其中的一個類型中將deleted字段做爲date類型,而在另外一個類型中將其做爲boolean字段。
在此之上須要考慮一點,若是同一個索引中存儲的各個實體若是隻有不多或者根本沒有一樣的字段,這種狀況會致使稀疏數據,而且會影響到Lucene的高效壓縮數據的能力。
基於這些緣由,將映射類型的概念從Elasticsearch中移除。
springboot | elasticsearch |
---|---|
2.0.0.RELEASE | 2.2.0 |
1.4.0.M1 | 1.7.3 |
1.3.0.RELEASE | 1.5.2 |
1.2.0.RELEASE | 1.4.4 |
1.1.0.RELEASE | 1.3.2 |
1.0.0.RELEASE | 1.1.1 |
一、None of the configured nodes are available 或者org.elasticsearch.transport.RemoteTransportException: Failed to deserialize exception response from stream
緣由:spring data elasticSearch 的版本與Spring boot、Elasticsearch版本不匹配。
這是版本之間的對應關係。Spring boot 1.3.5默認的elasticsearch版本是1.5.2,此時啓動1.7.2版本如下的Elasticsearch客戶端鏈接正常。
注:注意java的es默認鏈接端口是9300,9200是http端口,這兩個在使用中應注意區分。
二、Caused by: java.lang.IllegalArgumentException: @ConditionalOnMissingBean annotations must specify at least one bean (type, name or annotation)
緣由:spring boot是1.3.x版本,而es採用了2.x版本。在es的2.x版本去除了一些類,而這些類在spring boot的1.3.x版本中仍然被使用,致使此錯誤
以上解決參考下面的對應關係:
Spring Boot Version (x) | Spring Data Elasticsearch Version (y) | Elasticsearch Version (z) |
---|---|---|
x <= 1.3.5 | y <= 1.3.4 | z <= 1.7.2* |
x >= 1.4.x | 2.0.0 <=y < 5.0.0** | 2.0.0 <= z < 5.0.0** |
請必定注意版本兼容問題。這關係到不少maven依賴。Spring Data Elasticsearch Spring Boot version matrix
ik 分詞對應的版本關係:
Analyzer:
ik_smart
, ik_max_word
, Tokenizer: ik_smart
, ik_max_word
IK version | ES version |
---|---|
master | 6.x -> master |
6.2.2 | 6.2.2 |
6.1.3 | 6.1.3 |
5.6.8 | 5.6.8 |
5.5.3 | 5.5.3 |
5.4.3 | 5.4.3 |
5.3.3 | 5.3.3 |
5.2.2 | 5.2.2 |
5.1.2 | 5.1.2 |
1.10.6 | 2.4.6 |
1.9.5 | 2.3.5 |
1.8.1 | 2.2.1 |
1.7.0 | 2.1.1 |
1.5.0 | 2.0.0 |
1.2.6 | 1.0.0 |
1.2.5 | 0.90.x |
1.1.3 | 0.20.x |
1.0.0 | 0.16.2 -> 0.19.0 |
maven依賴:前提是依賴
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
配置文件:
# ES #開啓 Elasticsearch 倉庫(默認值:true) spring.data.elasticsearch.repositories.enabled=true #默認 9300 是 Java 客戶端的端口。9200 是支持 Restful HTTP 的接口 spring.data.elasticsearch.cluster-nodes = 127.0.0.1:9300 #spring.data.elasticsearch.cluster-name Elasticsearch 集羣名(默認值: elasticsearch) #spring.data.elasticsearch.cluster-nodes 集羣節點地址列表,用逗號分隔。若是沒有指定,就啓動一個客戶端節點 #spring.data.elasticsearch.propertie 用來配置客戶端的額外屬性 #存儲索引的位置 spring.data.elasticsearch.properties.path.home=/data/project/target/elastic #鏈接超時的時間 spring.data.elasticsearch.properties.transport.tcp.connect_timeout=120s
Spring-data-elasticsearch爲咱們提供了@Document
、@Field
等註解,若是某個實體須要創建索引,只須要加上這些註解便可
@Document
註解以後,默認狀況下這個實體中全部的屬性都會被創建索引、而且分詞。類型 | 屬性名 | 默認值 | 說明 |
---|---|---|---|
String | indexName | 無 | 索引庫的名稱,建議以項目的名稱命名 |
String | type | 「」 | 類型,建議以實體的名稱命名 |
short | shards | 5 | 默認分區數 |
short | replica | 1 | 每一個分區默認的備份數 |
String | refreshInterval | 「1s」 | 刷新間隔 |
String | indexStoreType | 「fs」 | 索引文件存儲類型 |
只是一個標識,並無屬性。
@Field默認是能夠不加的,默認全部屬性都會添加到ES中。加上@Field以後,@document默認把全部字段加上索引失效,只有家@Field 纔會被索引(同時也看設置索引的屬性是否爲no)
類型 | 屬性名 | 默認值 | 說明 |
---|---|---|---|
FieldType | type | FieldType.Auto | 自動檢測屬性的類型 |
FieldIndex | index | FieldIndex.analyzed | 默認狀況下分詞 |
boolean | store | false | 默認狀況下不存儲原文 |
String | searchAnalyzer | 「」 | 指定字段搜索時使用的分詞器 |
String | indexAnalyzer | 「」 | 指定字段創建索引時指定的分詞器 |
String[] | ignoreFields | {} | 若是某個字段須要被忽略 |
實現方式比較多,已經存在的接口,使用根據須要繼承便可:
一、CrudRepository接口
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> { <S extends T> S save(S entity); Optional<T> findById(ID primaryKey); Iterable<T> findAll(); long count(); void delete(T entity); boolean existsById(ID primaryKey); // … more functionality omitted. }
二、PagingAndSortingRepository接口
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> { Iterable<T> findAll(Sort sort); Page<T> findAll(Pageable pageable); }
例子:
分頁:
PagingAndSortingRepository<User, Long> repository = // … get access to a bean Page<User> users = repository.findAll(new PageRequest(1, 20));
計數:
interface UserRepository extends CrudRepository<User, Long> { long countByLastname(String lastname); }
三、其餘,參考官網
自定義查詢實現
那麼咱們如何自定義方法呢?咱們只要使用特定的單詞對方法名進行定義,那麼Spring就會對咱們寫的方法名進行解析,
該機制條前綴find…By
,read…By
,query…By
,count…By
,和get…By
從所述方法和開始分析它的其他部分。引入子句能夠包含進一步的表達式,如Distinct
在要建立的查詢上設置不一樣的標誌。然而,第一個By
做爲分隔符來指示實際標準的開始。在很是基礎的層次上,您能夠定義實體屬性的條件並將它們與And
和鏈接起來Or
。
interface PersonRepository extends Repository<User, Long> { List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname); // Enables the distinct flag for the query List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname); List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname); // Enabling ignoring case for an individual property List<Person> findByLastnameIgnoreCase(String lastname); // Enabling ignoring case for all suitable properties List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname); // Enabling static ORDER BY for a query List<Person> findByLastnameOrderByFirstnameAsc(String lastname); List<Person> findByLastnameOrderByFirstnameDesc(String lastname); }
構建查詢屬性算法原理:
如上例所示。在查詢建立時,確保解析的屬性是託管類的屬性。可是,你也能夠經過遍歷嵌套屬性來定義約束。假設Person x
有一個Address
和 ZipCode
。在這種狀況下,方法名稱爲
List<Person> findByAddressZipCode(ZipCode zipCode);
建立屬性遍歷x.address.zipCode
。解析算法首先將整個part(AddressZipCode
)做爲屬性進行解釋,而後檢查具備該名稱屬性的類。若是皮匹配成功,則使用該屬性。若是不是屬性,則算法拆分從右側的駝峯部分頭部和尾部,並試圖找出相應的屬性,在咱們的例子,AddressZip
和Code
。若是算法找到具備該頭部的屬性,它將採用尾部並繼續從那裏構建樹,而後按照剛剛描述的方式分割尾部。若是第一個分割不匹配,則算法將分割點移動到左側(Address
,ZipCode
)並繼續。
雖然這應該適用於大多數狀況,但算法仍可能會選擇錯誤的屬性。假設這個Person
類也有一個addressZip
屬性。該算法將在第一輪拆分中匹配,而且基本上選擇錯誤的屬性並最終失敗(由於addressZip
可能沒有code
屬性的類型)。
爲了解決這個歧義,你能夠\_
在你的方法名稱中使用手動定義遍歷點。因此咱們的方法名稱會像這樣結束:
List<Person> findByAddress_ZipCode(ZipCode zipCode);
因爲咱們將下劃線視爲保留字符,所以咱們強烈建議遵循標準的Java命名約定(即,不要在屬性名稱中使用下劃線,而應使用駝峯大小寫)
其餘分頁查詢
Page<User> findByLastname(String lastname, Pageable pageable); Slice<User> findByLastname(String lastname, Pageable pageable); List<User> findByLastname(String lastname, Sort sort);
也能夠用Java8 Stream查詢和sql語句查詢
@Query("select u from User u") Stream<User> findAllByCustomQueryAndStream(); Stream<User> readAllByFirstnameNotNull(); @Query("select u from User u") Stream<User> streamAllPaged(Pageable pageable);
有些在複雜的可使用es查詢語句
咱們可使用@Query註解進行查詢,這樣要求咱們須要本身寫ES的查詢語句
public interface BookRepository extends ElasticsearchRepository<Book, String> { @Query("{"bool" : {"must" : {"field" : {"name" : "?0"}}}}") Page<Book> findByName(String name,Pageable pageable); }
方法和es查詢轉換:
Keyword | Sample | Elasticsearch Query String |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在使用的時候沒有找到直接的例子,因爲between是轉換成range,因此須要範圍參數from和to,
舉例以下:
Page<Recruit> findByRecruitWorkAndRecruitCitysAndWorkTypeAndXjTimeBetween(String recruitWork, String recruitCitys, Integer workType, Date fromXjTime, Date toXjTime,Pageable pageable);
注意:
這裏必需要注意的是:只要使用了between參數,****XjTimeBetween(......,from,to) ,使用該方法的時候,必需要傳遞範圍參數from,to,不能同時爲空。
不然異常
org.springframework.dao.InvalidDataAccessApiUsageException: Range [* TO *] is not allowed at org.springframework.data.elasticsearch.core.query.Criteria.between(Criteria.java:304) at org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator.from(ElasticsearchQueryCreator.java:127) at org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator.and(ElasticsearchQueryCreator.java:76) at org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator.and(ElasticsearchQueryCreator.java:46) at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:109) at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:88) at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:73) at org.springframework.data.elasticsearch.repository.query.ElasticsearchPartQuery.createQuery(ElasticsearchPartQuery.java:102) at org.springframework.data.elasticsearch.repository.query.ElasticsearchPartQuery.execute(ElasticsearchPartQuery.java:51) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:499) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:477) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) at com.sun.proxy.$Proxy86.findByRecruitWorkAndRecruitCitysAndWorkTypeAndXjTimeBetween(Unknown Source) at com.zhimingdeng.service.impl.EsIndexServiceImpl.findByRecruitWorkAndRecruitCitysAndWorkTypeAndXjTimeBetween(EsIndexServiceImpl.java:155)
由於底層要求參數不能同時爲空
七 es時間類型注意
來源: http://www.cnblogs.com/guozp/p/8686904.html
對於Elasticsearch原生支持date類型,json格式經過字符來表示date類型。因此在用json提交日期至elasticsearch的時候,es會隱式轉換,把es認爲是date類型的字符串直接轉爲date類型,間字段內容實際上就是轉換成long類型做爲內部存儲的(因此徹底能夠接受其餘時間格式做爲時間字段的內容)。至於什麼樣的字符串es會認爲能夠轉換成date類型,參考elasticsearch官網介紹
date類型是包含時區信息的,若是咱們沒有在json表明日期的字符串中顯式指定時區,對es來講沒什麼問題,可是對於咱們來講可能會發現一些時間差8個小時的問題。
Elastic自己有一種特殊的時間格式,其形式如"2016-01-25T00:00:00",此格式爲ISO8601標準。具體時間日期格式要求能夠參見es官方文檔。
然而咱們在計算日期間隔,甚至按日分類的時候,每每須要把這個String時間轉化爲Unix時間戳(Unix Timestamp(時間戳))的形式,再進行計算。而一般,這個時間戳會以毫秒的形式(Java)保存在一個long類型裏面,這就涉及到了String與long類型的相互轉化。
此外在使用Java Client聚合查詢日期的時候,須要注意時區問題,由於默認的es是按照UTC標準時區算的,因此不設置的聚合統計結果是不正確的。默認不設置時區參數,es是安裝UTC的時間進行查詢的,因此分組的結果可能與預期不同。
JSON
沒有日期類型,所以在 Elasticsearch 中能夠表達成:
long
類型或秒級別的 integer
類型,好比: 1515150699465, 1515150699;
實際上無論日期以何種格式寫入,在 ES 內部都會先穿換成 UTC 時間並存儲爲 long
類型。日期格式能夠自定義,若是沒有指定的話會使用如下的默認格式:
"strict_date_optional_time||epoch_millis"
所以總結來講,無論哪一種能夠表示時間的格式寫入,均可以用來表示時間
因此這裏引出多種解決方案:
一、es 默認的是 utc 時間,而國內服務器是 cst 時間,首先有時間上的差距須要轉換。可是若是底層以及上層都統一用時間戳,完美解決時區問題。可是時間戳對咱們來講不直觀
二、咱們在往es提交日期數據的時候,直接提交帶有時區信息的日期字符串,如:「2016-07-15T12:58:17.136+0800」
三、還有另外的一種:
直接設置format爲你想要的格式,好比 "yyyy-MM-dd HH:mm:ss"
而後存儲的時候,指定格式,而且Mapping 也是指定相同的format
。
@Field( type = FieldType.Date, format = DateFormat.custom,pattern = date_optional_time" ) private Date gmtCreate;
我這裏是數據是從數據庫直接讀取,使用的datetime類型,原來直接使用的時候,拋異常:
MapperParsingException[failed to parse [***]]; nested: IllegalArgumentException[Invalid format: "格式"];
緣由是: jackson庫在轉換爲json的時候,將Date類型轉爲爲了long型的字符串表示,而咱們定義的是date_optional_time格式的字符串,因此解析錯誤,
具體的解決辦法:去掉註解中的format=DateFormat.date_optional_time,讓其使用默認的格式,也就是 'strict_date_optional_time||epoch_millis' , 既能接受 date_optional_time格式的,也能接受epoch_millis格式,因爲爲了查看更直觀感覺改成以下:
@Field( type = FieldType.Date, format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" ) private Date gmtCreate;
改爲這樣後,底層多種格式均可以存儲,若是沒有根據時間進行範圍查找,這裏基本上已經就告一段落了。
存儲的時候利用各類JSON對象,如 Jackson 等。存儲的時候就能夠用JSON Format一下再存儲,而後取出來後
@Field( type = FieldType.Date,
format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss" ) @JsonFormat (shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd HH:mm:ss",timezone="GMT+8") private Date xjTime;
有了這個註解後,
timezone="GMT+8" 主要是由於底層存放的數據日期時區是UTC,這裏轉換成GMT
時間範圍查找需求注意:
根據條件查詢的時候,時間範圍須要傳入range,這裏涉及到了兩種選擇,底層查詢方法實現的時候range的參數爲
1 date:
傳入的是date參數,而後就行查詢的時候,會報異常,由於我把日期轉成了yyyy-MM-dd HH:mm:ss,可是底層數據是2018-03-27T16:00:00.000Z這種格式,致使錯誤,詳細異常以下
org.elasticsearch.action.search.SearchPhaseExecutionException: all shards failed at org.elasticsearch.action.search.AbstractSearchAsyncAction.onFirstPhaseResult(AbstractSearchAsyncAction.java:206) at org.elasticsearch.action.search.AbstractSearchAsyncAction$1.onFailure(AbstractSearchAsyncAction.java:152) at org.elasticsearch.action.ActionListenerResponseHandler.handleException(ActionListenerResponseHandler.java:46) at org.elasticsearch.transport.TransportService$DirectResponseChannel.processException(TransportService.java:855) at org.elasticsearch.transport.TransportService$DirectResponseChannel.sendResponse(TransportService.java:833) at org.elasticsearch.transport.TransportService$4.onFailure(TransportService.java:387) at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:39) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: org.elasticsearch.ElasticsearchParseException: failed to parse date field [2018-03-27T16:00:00.000Z] with format [yyyy-MM-dd HH:mm:ss] at org.elasticsearch.common.joda.DateMathParser.parseDateTime(DateMathParser.java:203) at org.elasticsearch.common.joda.DateMathParser.parse(DateMathParser.java:67) at org.elasticsearch.index.mapper.core.DateFieldMapper$DateFieldType.parseToMilliseconds(DateFieldMapper.java:451) at org.elasticsearch.index.mapper.core.DateFieldMapper$DateFieldType.innerRangeQuery(DateFieldMapper.java:435) at org.elasticsearch.index.mapper.core.DateFieldMapper$DateFieldType.access$000(DateFieldMapper.java:199) at org.elasticsearch.index.mapper.core.DateFieldMapper$DateFieldType$LateParsingQuery.rewrite(DateFieldMapper.java:224) at org.apache.lucene.search.BooleanQuery.rewrite(BooleanQuery.java:278) at org.apache.lucene.search.IndexSearcher.rewrite(IndexSearcher.java:837) at org.elasticsearch.search.internal.ContextIndexSearcher.rewrite(ContextIndexSearcher.java:81) at org.elasticsearch.search.internal.DefaultSearchContext.preProcess(DefaultSearchContext.java:231) at org.elasticsearch.search.query.QueryPhase.preProcess(QueryPhase.java:103) at org.elasticsearch.search.SearchService.createContext(SearchService.java:676) at org.elasticsearch.search.SearchService.createAndPutContext(SearchService.java:620) at org.elasticsearch.search.SearchService.executeDfsPhase(SearchService.java:264) at org.elasticsearch.search.action.SearchServiceTransportAction$SearchDfsTransportHandler.messageReceived(SearchServiceTransportAction.java:360) at org.elasticsearch.search.action.SearchServiceTransportAction$SearchDfsTransportHandler.messageReceived(SearchServiceTransportAction.java:357) at org.elasticsearch.transport.TransportRequestHandler.messageReceived(TransportRequestHandler.java:33) at org.elasticsearch.transport.RequestHandlerRegistry.processMessageReceived(RequestHandlerRegistry.java:75) at org.elasticsearch.transport.TransportService$4.doRun(TransportService.java:376) at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) ... 3 common frames omitted Caused by: java.lang.IllegalArgumentException: Invalid format: "2018-03-27T16:00:00.000Z" is malformed at "T16:00:00.000Z" at org.joda.time.format.DateTimeParserBucket.doParseMillis(DateTimeParserBucket.java:187) at org.joda.time.format.DateTimeFormatter.parseMillis(DateTimeFormatter.java:826) at org.elasticsearch.common.joda.DateMathParser.parseDateTime(DateMathParser.java:200) ... 22 common frames omitted
解決:
傳入的date參數格式化成底層的類型
實現參考:
Page<Recruit> findByRecruitWorkAndRecruitCitysAndWorkTypeAndXjTimeBetween(String recruitWork, String recruitCitys, Integer workType, Date fromXjTime, Date toXjTime,Pageable pageable);
2 String
參數直接使用string,避免上層轉換成不合適的時間格式,使用框架底層本身轉換,避免錯誤。
實現參考:
實現參考:
Page<Recruit> findByRecruitWorkAndRecruitCitysAndWorkTypeAndXjTimeBetween(String recruitWork, String recruitCitys, Integer workType, String fromXjTime, String toXjTime,Pageable pageable);
https://stackoverflow.com/questions/29122071/elasticsearch-failed-to-parse-date
https://stackoverflow.com/questions/29496081/spring-data-elasticsearchs-field-annotation-not-working
https://stackoverflow.com/questions/32042430/elasticsearch-spring-data-date-format-always-is-long
我的認爲springboot 這種集成es的方法,最大的優勢是開發速度快,不要求對es一些api要求熟悉,能快速上手,即便以前對es不勝瞭解,也能經過方法名或者sql快速寫出本身須要的邏輯,而具體轉換成api層的操做,則有框架底層幫你實現。
缺點也顯而易見首先,使用的springboot的版本對es的版本也有了要求,不能超過es的某些版本號,部署時須要注意。第二,速度提高的同時,也失去了一些實用api的靈活性。一些比較靈活的條件封裝不能很容易的實現。各有利弊,各位權衡
來源: http://www.cnblogs.com/guozp/p/8686904.html