Lucene查詢方式總結
IndexReader的設計
--------------------------------------------------
IndexReader的建立需要消耗大量記憶體空間,
所以通過將IndexReader設計出屬性值,進行一次建立
整個專案週期就只有一個IndexReader
1.// IndexReader的設計
private static IndexReader reader = null;2.在構造方法中對IndexReader進行初始化
// 建立indexReader
reader = IndexReader.open(directory);
3.建立getSearch()方法,返回IndexSearch
private static IndexSearcher getSearch() {
return new IndexSearcher(reader);
}
4.最後在使用IndexReader完畢後,只需要關閉IndexSearch
// 最後只需要關閉search
search.close();
PS:因此此IndexReader屬於單例模式,在IndexReader過程中如果改變IndexWriter的索引,IndexReader所search出的資料將不會改變,除非重新構建一個新的IndexReader
程式碼優化:
// 優化
try { if (reader == null) { reader = IndexReader.open(directory); //reader = IndexReader.open(directory,false); //不設定為只讀的reader } else { // 如果Index索引改變了將返回一個新的reader,否則將返回null IndexReader read = IndexReader.openIfChanged(reader); if (read != null) { //把原來的reader給close()掉 reader.close(); reader = read; } } return new IndexSearcher(reader); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null;
//因為此時Reader已經為全域性範圍,用reader也能刪除文件
/*
* 使用reader刪除,會立即更新索引資訊(但不建議)
*/
// reader.deleteDocuments(new Term("id","1"));
// reader.close();
有時候整個專案週期中只有一個IndexWriter這時候,IndexWriter就不能關閉
那麼怎麼提交呢?
使用IndexWriter.commit()方法提交對索引操作後的資料
--------------------------------------------------------
Directory的幾種操作方式
--------------------------------------------------------
FSDirectory.open()。。系統會根據具體執行環境使用最佳方式開啟一個Directory
new RAMDirectory()。。就是將索引儲存在記憶體中。好處:速度快。壞處:不能持久化
RAMDirectory(Directory dir)。也可以將一個持久化好的directory放入記憶體中。
-------------------------------------------------------
lucene的搜尋_TermRange等基本搜尋
-------------------------------------------------------
1.建立IndexSearch
/*
* 建立IndexSearch的方法
*/
public IndexSearcher getSearch() {
try {
if (reader == null) {
reader = IndexReader.open(directory);
} else {
IndexReader read = IndexReader.openIfChanged(reader);
if (read != null) {
reader.close();
reader = read;
}
}
return new IndexSearcher(reader);
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
2.查詢的幾種
======精確查詢:
IndexSearcher search = getSearch();
Query query = new TermQuery(new Term(field, name));
TopDocs tds = search.search(query, num);
for (ScoreDoc sdc : tds.scoreDocs) {
Document doc = search.doc(sdc.doc);
}
search.close();
======基於字串的範圍查詢(TermRange)
// true表示閉區間
IndexSearcher search = getSearch();
Query query = new TermRangeQuery(field, start, end, true, true);
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);
======基於數字的範圍查詢(NumericRangeQuery.new...)
IndexSearcher search = getSearch();
// true表示閉區間
Query query = NumericRangeQuery.newIntRange(field, start, end,true, true);
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);
======PS:tds.totalHits是總記錄數,與我們傳入的num,沒有任何關係
eg:
// 基於範圍的查詢(引數:傳入的field,開始字元,結束字元,顯示數目)
public void SearchByTermRange(String field, String start, String end,int num) {
try {
IndexSearcher search = getSearch();
// 範圍查詢
// true表示閉區間(是否包含開始字元和結束字元,預設為true)
Query query = new TermRangeQuery(field, start, end, true, true);
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);
for (ScoreDoc sdc : tds.scoreDocs) {
Document doc = search.doc(sdc.doc);
System.out.println(sdc.doc + doc.get("name") + "["
+ doc.get("email") + "," + doc.get("id") + ","
+ doc.get("attach") + "]");
}
search.close();
} catch (IOException e) {
e.printStackTrace();
}
}
-----------------------------------------------------------------
lucene的搜尋_其他常用Query搜尋
-----------------------------------------------------------------
======字首搜尋(prefixquery)
Query query = new PrefixQuery(new Term(field, value));
======萬用字元搜尋(wildcardquery)
Query query = new WildcardQuery(new Term(field, value));
//使用方法sutil.SearchByWildCard("name", "l*", 3);
在傳入的value中可以使用萬用字元? 和 * ?表示匹配一個字元,*表示匹配任意多個字元。可以在任何位置使用。
=======可以連線多個條件(BooleanQuery)
BooleanQuery query = new BooleanQuery();
// Occur.Must表必須
//Occur.SHOULD表示可有可無
//Occur.MUST_NOT表示必須沒有
query.add(new TermQuery(new Term("name", "lili")), Occur.MUST);
query.add(new TermQuery(new Term("content", "hello")), Occur.MUST);
=======短語查詢(phrasequery)
PhraseQuery query = new PhraseQuery();
// setSlop()設定跳數,及兩個單詞之間有幾個單詞
query.setSlop(1);
// 設定field欄位,即哪兩個單詞
// 第一個term
query.add(new Term("content", "i"));
// 產生距離後的第二個term
query.add(new Term("content", "basketball"));
======模糊查詢(FuzzyQuery)
//會匹配有一個字元出錯的情況
Query query=new FuzzyQuery(new Term("name", "mirk"));
-------------------------------------------------------------
lucene的搜尋_基於QueryParser的搜尋
-------------------------------------------------------------
//基於字串操作
public void SearchByQueryParse(Query query,int num){
try {
IndexSearcher search = getSearch();
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);
for (ScoreDoc sdc : tds.scoreDocs) {
Document doc = search.doc(sdc.doc);
System.out.println(sdc.doc + doc.get("name") + "["
+ doc.get("email") + "," + doc.get("id") + ","
+ doc.get("attach") + "]");
}
search.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//使用query查詢(建立queryparser,再通過queryparser建立query)
// 1.建立Parse物件(設定預設搜尋域為content)
QueryParser parse = new QueryParser(Version.LUCENE_35, "content",new StandardAnalyzer(Version.LUCENE_35));
// 改變空格的預設操作(改為AND型)
parse.setDefaultOperator(Operator.AND);
// 開啟第一個字元的萬用字元匹配(*xxx,?xxx),預設關閉,因為效率比較低
parse.setAllowLeadingWildcard(true);
// 2.通過parse生成query(搜尋content域中包含有like的)
Query query = parse.parse("like");
// 能夠一直加條件(空格預設就是OR)
query = parse.parse("basketball i");
// 改變搜尋域(域:值)
query = parse.parse("name:mark");
// 同樣能進行*或?的萬用字元匹配(萬用字元預設不能放在首位)
query = parse.parse("name:*i");
// name中不包含mark,但是content中包含basketball(-和+必須放在域說明的前面)
query = parse.parse("- name:mark + basketball");
// id的1~3(TO表示一個閉區間,TO必須是大寫的)
query = parse.parse("id:[1 TO 3]");
// {}表示1~3的開區間匹配
query = parse.parse("id:{1 TO 3}");
// name域值是lili或mark,預設域值是game
query = parse.parse("name:(lili OR mark) AND game");
// 兩個‘’號表示短語匹配
query = parse.parse("'i like basketball'");
// 表示i basketball之間有一個單詞遺漏的匹配
query = parse.parse("\"i basketball\"~1");
// 加個~就能模糊查詢mark
query = parse.parse("name:mirk~");
// 沒有辦法匹配數字範圍(自己擴充套件parse)
query = parse.parse("attach:[1 TO 3]");
sutil.SearchByQueryParse(query, 5);
------------------------------------------------------------
簡單分頁搜尋
------------------------------------------------------------
Lucene通過再查詢的方式:將所有資料取出,再進行分段分頁
3.5以後使用的是searchAfter
//第一種分頁方式(通過取出全部資料,再通過start和end對資料進行分頁)
public void searchPage(String query,int pageIndex,int pageSize) {
try {
Directory dir = FileIndexUtils.getDirectory();
IndexSearcher searcher = getSearcher(dir);
QueryParser parser = new QueryParser(Version.LUCENE_35,"content",new StandardAnalyzer(Version.LUCENE_35));
Query q = parser.parse(query);
TopDocs tds = searcher.search(q, 500);
ScoreDoc[] sds = tds.scoreDocs;
int start = (pageIndex-1)*pageSize;
int end = pageIndex*pageSize;
for(int i=start;i<end;i++) {
Document doc = searcher.doc(sds[i].doc);
System.out.println(sds[i].doc+":"+doc.get("path")+"-->"+doc.get("filename"));
}
searcher.close();
} catch (org.apache.lucene.queryParser.ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
-----------------------------------------------------------
lucene的搜尋_基於searchAfter的實現(Lucene3.5之後)
-----------------------------------------------------------
/**
* 根據頁碼和分頁大小獲取上一次的最後一個ScoreDoc
*/
private ScoreDoc getLastScoreDoc(int pageIndex,int pageSize,Query query,IndexSearcher searcher) throws IOException {
if(pageIndex==1)return null;//如果是第一頁就返回空
int num = pageSize*(pageIndex-1);//獲取上一頁的數量
//每次只取上面所有的元素
TopDocs tds = searcher.search(query, num);
return tds.scoreDocs[num-1];
}
public void searchPageByAfter(String query,int pageIndex,int pageSize) {
try {
Directory dir = FileIndexUtils.getDirectory();
IndexSearcher searcher = getSearcher(dir);
QueryParser parser = new QueryParser(Version.LUCENE_35,"content",new StandardAnalyzer(Version.LUCENE_35));
Query q = parser.parse(query);
//先獲取上一頁的最後一個元素
ScoreDoc lastSd = getLastScoreDoc(pageIndex, pageSize, q, searcher);
//通過最後一個元素搜尋下頁的pageSize個元素
TopDocs tds = searcher.searchAfter(lastSd,q, pageSize);
for(ScoreDoc sd:tds.scoreDocs) {
Document doc = searcher.doc(sd.doc);
System.out.println(sd.doc+":"+doc.get("path")+"-->"+doc.get("filename"));
}
searcher.close();
} catch (org.apache.lucene.queryParser.ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
程式碼片段
package test.lucene.index;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.NumericField;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeFilter;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
public class SearchUtil {
/*
* 假設6個文件
*/
private String[] ids = { "1", "2", "3", "4", "5", "6" };
private String[] emails = { "[email protected]", "[email protected]", "[email protected]",
"[email protected]", "[email protected]", "[email protected]" };
private String[] contents = { "hello boy,i like pingpang", "like boy",
"xx bye i like swim", "hehe, i like basketball",
"dd fsfs, i like movie", "hello xxx,i like game" };
private int[] attachs = { 2, 3, 1, 4, 5, 5 };
private String[] names = { "lili", "wangwu", "lisi", "jack", "tom", "mark" };
// 設定加權map
private Map<String, Float> scores = new HashMap<String, Float>();
private Directory directory;
private IndexReader reader;
public SearchUtil() {
directory = new RAMDirectory();
}
/*
* 新增索引
*/
public void index() {
IndexWriter writer = null;
try {
writer = new IndexWriter(directory, new IndexWriterConfig(
Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)));
writer.deleteAll();
// 建立documents
Document document = null;
for (int i = 0; i < ids.length; i++) {
document = new Document();
document.add(new Field("id", ids[i], Field.Store.YES,
Field.Index.NOT_ANALYZED_NO_NORMS));
document.add(new Field("email", emails[i], Field.Store.YES,
Field.Index.NOT_ANALYZED)); // 不分詞
document.add(new Field("content", contents[i], Field.Store.NO,
Field.Index.ANALYZED));
document.add(new Field("name", names[i], Field.Store.YES,
Field.Index.NOT_ANALYZED));
// 為數字新增索引
document.add(new NumericField("attach", Field.Store.YES, true)
.setIntValue(attachs[i]));
/*
* document.setBoost(float) 設定評級
*/
String et = emails[i].substring(emails[i].lastIndexOf("@") + 1);
// System.out.println(et);
if (scores.containsKey(et)) {
document.setBoost(scores.get(et));
} else {
document.setBoost(0.5f);
}
writer.addDocument(document);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
writer = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/*
* 建立IndexSearch的方法
*/
public IndexSearcher getSearch() {
try {
if (reader == null) {
reader = IndexReader.open(directory);
} else {
IndexReader read = IndexReader.openIfChanged(reader);
if (read != null) {
reader.close();
reader = read;
}
}
return new IndexSearcher(reader);
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// 精確匹配查詢
public void SearchByTerm(String field, String name, int num) {
try {
IndexSearcher search = getSearch();
Query query = new TermQuery(new Term(field, name));
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);
for (ScoreDoc sdc : tds.scoreDocs) {
Document doc = search.doc(sdc.doc);
System.out.println(sdc.doc + doc.get("name") + "["
+ doc.get("email") + "," + doc.get("id") + ","
+ doc.get("attach") + "]");
}
search.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 基於字串的範圍的查詢
public void SearchByTermRange(String field, String start, String end,
int num) {
try {
IndexSearcher search = getSearch();
// 範圍查詢
// true表示閉區間
Query query = new TermRangeQuery(field, start, end, true, true);
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);
for (ScoreDoc sdc : tds.scoreDocs) {
Document doc = search.doc(sdc.doc);
System.out.println(sdc.doc + doc.get("name") + "["
+ doc.get("email") + "," + doc.get("id") + ","
+ doc.get("attach") + "]");
}
search.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 基於數字的範圍的查詢
public void SearchByNumricRange(String field, int start, int end, int num) {
try {
IndexSearcher search = getSearch();
// 範圍查詢
// true表示閉區間
Query query = NumericRangeQuery.newIntRange(field, start, end,
true, true);
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);
for (ScoreDoc sdc : tds.scoreDocs) {
Document doc = search.doc(sdc.doc);
System.out.println(sdc.doc + doc.get("name") + "["
+ doc.get("email") + "," + doc.get("id") + ","
+ doc.get("attach") + "]");
}
search.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 字首搜尋
public void SearchByPrefix(String field, String value, int num) {
try {
IndexSearcher search = getSearch();
Query query = new PrefixQuery(new Term(field, value));
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);
for (ScoreDoc sdc : tds.scoreDocs) {
Document doc = search.doc(sdc.doc);
System.out.println(sdc.doc + doc.get("name") + "["
+ doc.get("email") + "," + doc.get("id") + ","
+ doc.get("attach") + "]");
}
search.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 萬用字元搜尋
public void SearchByWildCard(String field, String value, int num) {
try {
IndexSearcher search = getSearch();
Query query = new WildcardQuery(new Term(field, value));
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);
for (ScoreDoc sdc : tds.scoreDocs) {
Document doc = search.doc(sdc.doc);
System.out.println(sdc.doc + doc.get("name") + "["
+ doc.get("email") + "," + doc.get("id") + ","
+ doc.get("attach") + "]");
}
search.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 多個條件搜尋
public void SearchByBoolean(int num) {
try {
IndexSearcher search = getSearch();
BooleanQuery query = new BooleanQuery();
// Occur.Must表必須 Occur.SHOULD表示可有可無 Occur.MUST_NOT表示必須沒有
query.add(new TermQuery(new Term("name", "lili")), Occur.MUST);
query.add(new TermQuery(new Term("content", "hello")), Occur.MUST);
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);
for (ScoreDoc sdc : tds.scoreDocs) {
Document doc = search.doc(sdc.doc);
System.out.println(sdc.doc + doc.get("name") + "["
+ doc.get("email") + "," + doc.get("id") + ","
+ doc.get("attach") + "]");
}
search.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 短語查詢
public void SearchByPhrase(int num) {
try {
IndexSearcher search = getSearch();
PhraseQuery query = new PhraseQuery();
// setSlop()設定跳數,及兩個單詞之間有幾個單詞
query.setSlop(1);
// 設定field欄位,即哪兩個單詞
query.add(new Term("content", "i"));
query.add(new Term("content", "basketball"));
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);
for (ScoreDoc sdc : tds.scoreDocs) {
Document doc = search.doc(sdc.doc);
System.out.println(sdc.doc + doc.get("name") + "["
+ doc.get("email") + "," + doc.get("id") + ","
+ doc.get("attach") + "]");
}
search.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 模糊查詢
public void SearchByFuzzy(int num) {
try {
IndexSearcher search = getSearch();
Query query=new FuzzyQuery(new Term("name", "mirk"));
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);
for (ScoreDoc sdc : tds.scoreDocs) {
Document doc = search.doc(sdc.doc);
System.out.println(sdc.doc + doc.get("name") + "["
+ doc.get("email") + "," + doc.get("id") + ","
+ doc.get("attach") + "]");
}
search.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//基於字串操作
public void SearchByQueryParse(Query query,int num){
try {
IndexSearcher search = getSearch();
TopDocs tds = search.search(query, num);
System.out.println("一共查詢了:" + tds.totalHits);
for (ScoreDoc sdc : tds.scoreDocs) {
Document doc = search.doc(sdc.doc);
System.out.println(sdc.doc + doc.get("name") + "["
+ doc.get("email") + "," + doc.get("id") + ","
+ doc.get("attach") + "]");
}
search.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package test.lucene.index;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.queryParser.QueryParser.Operator;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.Version;
import org.junit.Before;
import org.junit.Test;
public class SearchTest {
private SearchUtil sutil;
@Before
public void init() throws Exception {
sutil = new SearchUtil();
}
@Test
public void searchByterm() {
sutil.index();
sutil.SearchByTerm("name", "mark", 3);
}
@Test
public void searchByRangeTerm() {
sutil.index();
sutil.SearchByTermRange("id", "1", "3", 10);
// 查詢name以a開頭和s結尾的
sutil.SearchByTermRange("name", "a", "s", 10);
// 由於attach是數字型別,使用termrange無法查詢
sutil.SearchByTermRange("attach", "1", "5", 10);
}
@Test
public void searchByNumricRange() {
sutil.index();
// 由於attach是數字型別,使用NumricRange進行查詢
sutil.SearchByNumricRange("attach", 2, 5, 10);
}
@Test
public void searchByPrefix() {
sutil.index();
// 字首搜尋
sutil.SearchByPrefix("name", "l", 3);
}
@Test
public void searchByWildCard() {
sutil.index();
// 萬用字元搜尋
sutil.SearchByWildCard("name", "l*", 3);
}
@Test
public void searchByBoolean() {
sutil.index();
// 多條件查詢
sutil.SearchByBoolean(3);
}
@Test
public void searchByPhrase() {
sutil.index();
// 短語查詢
sutil.SearchByPhrase(5);
}
@Test
public void searchByFuzzy() {
sutil.index();
// 模糊查詢
sutil.SearchByFuzzy(5);
}
@Test
public void searchByqueryParse() throws Exception {
sutil.index();
// 1.建立Parse物件(設定預設搜尋域為content)
QueryParser parse = new QueryParser(Version.LUCENE_35, "content",
new StandardAnalyzer(Version.LUCENE_35));
// 改變空格的預設操作(改為AND型)
parse.setDefaultOperator(Operator.AND);
// 開啟第一個字元的萬用字元匹配(*xxx,?xxx),預設關閉,因為效率比較低
parse.setAllowLeadingWildcard(true);
// 2.通過parse生成query(搜尋content域中包含有like的)
Query query = parse.parse("like");
// 能夠一直加條件(空格預設就是OR)
query = parse.parse("basketball i");
// 改變搜尋域(域:值)
query = parse.parse("name:mark");
// 同樣能進行*或?的萬用字元匹配(萬用字元預設不能放在首位)
query = parse.parse("name:*i");
// name中不包含mark,但是content中包含basketball(-和+必須放在域說明的前面)
query = parse.parse("- name:mark + basketball");
// id的1~3(TO表示一個閉區間,TO必須是大寫的)
query = parse.parse("id:[1 TO 3]");
// {}表示1~3的開區間匹配
query = parse.parse("id:{1 TO 3}");
// name域值是lili或mark,預設域值是game
query = parse.parse("name:(lili OR mark) AND game");
// 兩個‘’號表示短語匹配
query = parse.parse("'i like basketball'");
// 表示i basketball之間有一個單詞遺漏的匹配
query = parse.parse("\"i basketball\"~1");
// 加個~就能模糊查詢mark
query = parse.parse("name:mirk~");
// 沒有辦法匹配數字範圍(自己擴充套件parse)
query = parse.parse("attach:[1 TO 3]");
sutil.SearchByQueryParse(query, 5);
}
}
相關推薦
Lucene查詢方式總結
--------------------------------------------------IndexReader的設計--------------------------------------------------IndexReader的建立需要消耗大量記憶體
SQLAlchemy 幾種查詢方式總結
記錄總數查詢: from sqlalchemy import func # count User records, without # using a subquery. session.query(func.count(User.id)) # return count of user "id" group
Spring data jpa 複雜動態查詢方式總結
一.Spring data jpa 簡介 首先我並不推薦使用jpa作為ORM框架,畢竟對於負責查詢的時候還是不太靈活,還是建議使用mybatis,自己寫sql比較好.但是如果公司用這個就沒辦法了,可以學習一下,對於簡單查詢還是非常好用的. 首先JPA是Java
lucene多種查詢方式
package junit; import java.io.File; import java.io.IOException; import java.text.ParseException; import java.util.ArrayList; import java.util.List; imp
MySQL索引及查詢優化總結
存儲 一行 -1 type 一定的 關鍵技術 表示 智能 string類型 一個簡單的對比測試 前面的案例中,c2c_zwdb.t_file_count表只有一個自增id,FFileName字段未加索引的sql執行情況如下: 在上圖中,type=all,key=nul
[OS] Linux進程、線程通信方式總結
信號量 all http 命名 信號 .com 數據結構 rem pip 轉自:http://blog.sina.com.cn/s/blog_64b9c6850100ub80.html Linux系統中的進程通信方式主要以下幾種: 同一主機上的進程通信方式 * UNI
C#打開SDE數據庫的幾種方式總結
tex 用戶 ops 總結 param word editor conn tor 轉自謝燦軟件原文 C#打開SDE數據庫的幾種方式總結 1.通過指定連接屬性參數打開數據庫 /// <param name="server">數據庫服務器名&
CSS居中方式總結
str code pad enter align play otto 總結 相等 1.text-align:center; 使用以上方式居中是將父級容器中display:inline;的行內元素或者文字進行水平居中。 2.inline-height:(height)值;
樣式導入方式總結
shee sea icon 問題 itl ica span 比較 content link與import <link href="index.css" rel="stylesheet"> <style type="text/css"> @im
Elasticsearch學習之多種查詢方式
完全 mar commerce 生產 pro 命令行 str 令行 {} 1. query string search 搜索全部商品:GET /ecommerce/product/_search took:耗費了幾毫秒 timed_out:是否超時,這裏是沒有
Hbase 統計表行數的3種方式總結
bsp ping love and interval board jar ive add 有些時候需要我們去統計某一個Hbase表的行數,由於hbase本身不支持SQL語言,只能通過其他方式實現。可以通過一下幾種方式實現hbase表的行數統計工作:1.count命令最直接的
9.9-全棧Java筆記:遍歷集合的N種方式總結&Collections工具類
java遍歷集合的N種方式總結【示例1】遍歷List方法1,使用普通for循環for(int i=0;i<list.size();i++){ //list為集合的對象名 String temp = (String)list.get(i); System.out.println
文本與集合的讀取寫入方式總結
void space -1 方式 static div throws col arraylist //1.從文本中讀取並添加到集合,按行讀取 1 public static void main(String[] args) throws IOException { 2
JS對象繼承的幾種方式總結
tor style div on() 引用 super 繼承 不兼容 font 今天學習了一下js的繼承,js中的繼承主要分四種,原型繼承,構造函數繼承,call/apply繼承以及es6的extend繼承。1.原型繼承:原型繼承主要利用js對象的prototype引用父類
JavaScript創建對象的幾種方式總結
引用 常用 添加 耦合 取代 共享 fun 支持 高程 ECMA把對象定義為:無序屬性的集合,其屬性可以包含基本值、對象或者函數。 1. 使用Object構造函數創建對象 創建自定義對象的最簡單的方式就是創建一個Object的實例,然後再為它添加屬性和方法。
JavaScript實現繼承的幾種方式總結一
相同 實踐 extend sta 執行 instance () class new 雖然在ES6中有了繼承,使用extends關鍵字就能實現。本篇講的不是這種,而是ES6之前的幾種實現繼承的方式。 (一)原型鏈 ECMAScript中將原型鏈作為實現繼承的主要方法。其基本思
浮點數float累加誤差解決方式總結
turn ble should 也有 方法 git 如果 precision https 首先是float累加產生誤差的原因,該部分轉自:http://blog.csdn.net/zhrh0096/article/details/38589067 1. 浮點數IEEE 7
Hibernate學習10——Hibernate 查詢方式
9.png property ice pub gets reat sed desc ring 本章主要是以查詢Student的例子: Student.java: package com.cy.model; public class Student { priv
Asp.Net中的三種分頁方式總結
rom chang clas 綁定 select proc dll xtend tinc 本人ASP.net初學,網上找了一些分頁的資料,看到這篇文章,沒看到作者在名字,我轉了你的文章,只為我可以用的時候方便查看,2010的文章了,不知道這技術是否過期。 以下才是正文
Linux進程間通信的幾種方式總結--linux內核剖析(七)
字節流 標準 包含 down pro trac posix共享內存 ++ 實現 進程間通信概述 進程通信的目的 傳輸數據 一個進程須要將它的數據發送給還有一個進程。發送的數據量在一個字節到幾M字節之間 共享數據 多個進程想要操作共享