Java操作mongodb的模糊查询和精确查询_MongoDB_脚本之

作者:计算机专家

本意是想查查mongo数据库的int类型的like怎么查,但是好像没 解决这个问题。

最近在学习Lucene的过程中遇到了需要多域搜索并排序的问题,在网上找了找,资料不是很多,现在都列出来,又需要的可以自己认真看看,都是从其他网站粘贴过来的,所以比较乱,感谢原创的作者们! 
    使用MultiFieldQueryParser类即可。 

1.针对多个域的一次性查询

精确查询;模糊查询;分页查询,每页多少:按某个字段排序:查询数量:大于,小于,等于;且,或,某个字段不为空,某个字段不存在,查询在某个范围内,删除等等查询。

示例代码: 

1.1.三种方案    

    使用lucene构造搜索引擎的时候,如果要针对多个域进行一次性查询,一般来说有三种方法:

    第一种实现方法是创建多值的全包含域的文本进行索引,这个方案最简单。但是这个防范有个缺点:你不能直接对每个域的加权进行控制。

    第二种方法是使用MultiFieldQueryParser,它是QueryParser的子类,它会在后台程序中实例化一个QueryParser对象,用来针对每个域进行查询表达式的解析,然后使用BooleanQuery将查询结果合并起来。当程序向BooleanQuery添加查询子句时,默认操作符OR被用于最简单的解析方法中。为了实现更好的控制,布尔操作符可以使用BooleanClause的常量指定给每个域。如果需要指定的话可以使用BooleanClause.Occur.MUST,如果禁止指定可以使用BooleanClause.Occur.MUST_NOT,或者普通情况为BooleanClause.Occur.SHOULD。下面的程序展示的是如何创建MultiFieldQueryParser类的方法:

[java] view plaincopy

  1. // 在这四个域中检索  
  2. String[] fields = { "phoneType", "name", "category", "price" };  
  3. Query query = new MultiFieldQueryParser(Version.LUCENE_36, fields, analyzer).parse(keyword);  

    第三种方法就是使用高级DisjunctionMaxQuery类,它会封装一个或者多个任意的查询,将匹配的文档进行OR操作。

一. 常用查询:

Java代码 

1.2.方案选择

    以上三种方案中,并不是第三种方案最好,也不是第一种方案就最差。哪种实现方式更适合你的应用程序呢?答案是“看情况”,因为这里存在一些取舍。全包含域是一个简单的解决方案——但这个方案只能对搜索结果进行简单的排序并且可能浪费磁盘空间(程序可能对同样的文本索引两次),但这个方案可能会获得最好的搜索性能。

    MultiFieldQueryParser生成的BooleanQuery会计算所有查询所匹配的文档评分的总和(DisjunctionMaxQuery则只选取最大评分),然后它能够实现针对每个域的加权。你必须对以上3中解决方案都进行测试,同时需要一起考虑搜索性能和搜索相关性,然后再找出最佳方案。

 

  1. 查询一条数据:(多用于保存时判断db中是否已有当前数据,这里 is 精确匹配,模糊匹配 使用regex...)

    public PageUrl getByUrl { return findOne(new Query.is; }

  2. 查询多条数据:linkUrl.id 属于分级查询

    public List getPageUrlsByUrl(int begin, int end,String linkUrlid) { Query query = new Query(); query.addCriteria(Criteria.where.is; return find(query.limit.skip, PageUrl.class); }

 图片 1)

2.在结果中查询

3.模糊查询:-----关键字---regex

  1. package com.lucene.search;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException; 54com.cn  
  5.   
  6. import org.apache.lucene.analysis.standard.StandardAnalyzer;  
  7. import org.apache.lucene.queryParser.MultiFieldQueryParser;  
  8. import org.apache.lucene.search.BooleanClause;  
  9. import org.apache.lucene.search.Hits;  
  10. import org.apache.lucene.search.IndexSearcher;  
  11. import org.apache.lucene.search.Query;  
  12. import org.apache.lucene.store.Directory;  
  13. import org.apache.lucene.store.FSDirectory;  
  14.   
  15. public class Searcher {  
  16.   
  17. feedom.net  
  18.     public static void main(String[] args) throws Exception {  
  19.         File indexDir = new File("C:\target\index\book");  
  20.         if (!indexDir.exists() || !indexDir.isDirectory()) {  
  21.             throw new IOException();  
  22.         }  
  23.         search(indexDir);  
  24.     }  
  25.   
  26.     public static void search(File indexDir) throws Exception {  
  27.   
  28.         Directory fsDir = FSDirectory.getDirectory(indexDir);  
  29.         IndexSearcher searcher = new IndexSearcher(fsDir);  
  30.   
  31.         String[] queries = { "中文版", "8*" };  
  32.         String[] fields = { "name", "isbn" };  
  33.         BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD };  
  34.         Query query = MultiFieldQueryParser.parse(queries, fields, clauses, new StandardAnalyzer());  
  35.   
  36.         Hits hits = searcher.search(query);  
  37.         System.out.println("共有" + searcher.maxDoc() + "条索引,命中" + hits.length() + "条");  
  38.         for (int i = 0; i < hits.length(); i++) {  
  39.             int DocId = hits.id(i);  
  40.             String DocName = hits.doc(i).get("name");  
  41.             String DocIsbn = hits.doc(i).get("isbn");  
  42.             String DocPblDt = hits.doc(i).get("pbl_dt");  
  43.             System.out.println(DocId + ":" + DocName + " ISBN:" + DocIsbn + " PBLDT:" + DocPblDt);  
  44.         }  
  45.     }  
  46. }  

2.1.两种方案

    在检索结果中再次进行检索,是一个很常见的需求,一般有两种方案可以选择:

    ①使用QueryFilter把第一个查询当作一个过滤器处理;

    ②用BooleanQuery把前后两个查询结合起来,并且使用BooleanClause.Occur.MUST。

    针对第一种方法,我需要解释一下。QueryFilter在Lucene的2.x版本中是存在的,但是在3.x中,lucene的API中这个类已经被废弃了,无法再找到。如果你的项目使用的是lucene是3.x,但是你又一定要使用QueryFilter,那么你必须自己创建一个QueryFilter类,然后将2.x中QueryFilter的源代码复制过来。你可能会说,直接在工程中同时使用lucene2.x和3.x的核心jar文件不就行了吗。但遗憾的是,一个工程下,是不能同时使用不同版本的lucene的。

public long getProcessLandLogsCount(List conditions) { Query query = new Query(); if (conditions != null && conditions.size { for (Condition condition : conditions) { query.addCriteria(Criteria.where.regex(".*?\" +condition.getValue; } } return count(query, ProcessLandLog.class); } 

Java代码 

2.2.QueryFilter方案

上文已经说了,如果一定要使用QueryFilter,由于lucene2.x中没有QueryFilter的API,所以自己要写一个QueryFilter,QueryFilter的源代码在lucene2.x中是这样的:

[java] view plaincopy

  1. import org.apache.lucene.search.CachingWrapperFilter;  
  2. import org.apache.lucene.search.Query;  
  3. import org.apache.lucene.search.QueryWrapperFilter;  
  4.   
  5. public class QueryFilter extends CachingWrapperFilter {  
  6.   
  7.     /** 
  8.      * Constructs a filter which only matches documents matching 
  9.      * <code>query</code>. 
  10.      */  
  11.     public QueryFilter(Query query) {  
  12.         super(new QueryWrapperFilter(query));  
  13.     }  
  14.   
  15.     public boolean equals(Object o) {  
  16.         return super.equals((QueryFilter) o);  
  17.     }  
  18.   
  19.     public int hashCode() {  
  20.         return super.hashCode() ^ 0x923F64B9;  
  21.     }  
  22. }  

第一种方案的例子程序如下:

[java] view plaincopy

  1. //简单实现对keyword的搜索  
  2.  public static void search(String keyword) throws IOException, ParseException {  
  3.          QueryParser queryParser = new QueryParser("content",new SimpleAnalyzer());  
  4.          Query query = queryParser.parse(keyword.trim());  
  5.          QueryFilter filter = new QueryFilter(query);  
  6.          //检索  
  7.          search(query, filter);  
  8.  }  
  9.    
  10.  //在搜索oldKeyword的结果集中搜索newKeyword  
  11.  public static void searchInResult(String newKeyword, String oldKeyword) throws ParseException, IOException {                  
  12.          QueryParser queryParser = new QueryParser("content",new SimpleAnalyzer());  
  13.          Query query = queryParser.parse(newKeyword.trim());  
  14.          Query oldQuery = queryParser.parse(oldKeyword.trim());  
  15.          QueryFilter oldFilter = new QueryFilter(oldQuery);  
  16.          CachingWrapperFilter filter = new CachingWrapperFilter(oldFilter);  
  17.          //检索  
  18.          search(query, filter);  
  19.  }  
  20.    
  21.  private static void search(Query query, Filter filter) throws IOException, ParseException {  
  22.          IndexSearcher ins = new IndexSearcher("d:/tesindex");  
  23.          Hits hits = ins.search(query, filter);  
  24.          for (int i = 0; i < hits.length(); i++) {  
  25.                  Document doc = hits.doc(i);  
  26.                  System.out.println(doc.get("content"));  
  27.          }  
  28.  }  

最下面,我在代码亲自实践过的模糊查询,只支持字段属性是字符串的查询,你要是查字段属性是int的模糊查询,还真没辙。

 图片 2)

2.3.BooleanQuery方案

    使用BooleanQuery来实现在结果中检索的过程是这样的,首先通过关键字keyword1正常检索,当用户需要在检索结果中再通过关键字keyword2检索的时候,通过构建BooleanQuery,来实现对在结果中检索的效果。这里要注意,这两个关键字都要使用BooleanClause.Occur.MUST。

[java] view plaincopy

  1. //创建BooleanQuery  
  2. BooleanQuery booleanQuery = new BooleanQuery();  
  3. //多域检索,在这四个域中检索  
  4. String[] fields = { "phoneType", "name", "category","free" };  
  5. Query multiFieldQuery = new MultiFieldQueryParser(Version.LUCENE_36, fields, analyzer).parse(keyword);  
  6. //将multiFieldQuery添加到BooleanQuery中  
  7. booleanQuery.add(multiFieldQuery, BooleanClause.Occur.MUST);  
  8. //如果osKeyword不为空  
  9. if(osKeyword != null && !osKeyword.equals("") && !osKeyword.equals("null")){  
  10.     TermQuery osQuery = new TermQuery(new Term("phoneType",osKeyword));   
  11.     //将osQuery添加到BooleanQuery中  
  12.     booleanQuery.add(osQuery, BooleanClause.Occur.MUST);  
  13. }  

4.gte: 大于等于,lte小于等于...注意查询的时候各个字段的类型要和mongodb中数据类型一致

  1. package com.lucene.search;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5.   
  6. import org.apache.lucene.analysis.standard.StandardAnalyzer;  
  7. import org.apache.lucene.queryParser.MultiFieldQueryParser;  
  8. import org.apache.lucene.search.BooleanClause;  
  9. import org.apache.lucene.search.Hits;  
  10. import org.apache.lucene.search.IndexSearcher;  
  11. import org.apache.lucene.search.Query;  
  12. import org.apache.lucene.store.Directory;  
  13. import org.apache.lucene.store.FSDirectory;  
  14.   
  15. public class Searcher {  
  16.   
  17.     public static void main(String[] args) throws Exception {  
  18.         File indexDir = new File("C:\target\index\book");  
  19.         if (!indexDir.exists() || !indexDir.isDirectory()) {  
  20.             throw new IOException();  
  21.         }  
  22.         search(indexDir);  
  23.     }  
  24.   
  25.     public static void search(File indexDir) throws Exception {  
  26.   
  27.         Directory fsDir = FSDirectory.getDirectory(indexDir);  
  28.         IndexSearcher searcher = new IndexSearcher(fsDir);  
  29.   
  30.    String[] queries = { "中文版", "8*" };  
  31.    String[] fields = { "name", "isbn" };  
  32.    BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD };  
  33.         Query query = MultiFieldQueryParser.parse(queries, fields, clauses, new StandardAnalyzer());  
  34.   
  35.         Hits hits = searcher.search(query);  
  36.         System.out.println("共有" + searcher.maxDoc() + "条索引,命中" + hits.length() + "条");  
  37.         for (int i = 0; i < hits.length(); i++) {  
  38.             int DocId = hits.id(i);  
  39.             String DocName = hits.doc(i).get("name");  
  40.             String DocIsbn = hits.doc(i).get("isbn");  
  41.             String DocPblDt = hits.doc(i).get("pbl_dt");  
  42.             System.out.println(DocId + ":" + DocName + " ISBN:" + DocIsbn + " PBLDT:" + DocPblDt);  
  43.         }  
  44.     }  
  45. }  

3.检索结果分页

public List getProcessLandLogs(int begin,int end,List conditions,String orderField,Direction direction) { Query query = new Query(); if (conditions != null && conditions.size { for (Condition condition : conditions) { if.equals{ query.addCriteria(Criteria.where.gte); //gte: 大于等于 }else if.equals{ query.addCriteria(Criteria.where.gte); }else{ query.addCriteria(Criteria.where.is); } } } return find(query.limit.skip.with(new Sort(new Sort.Order(direction, orderField))), ProcessLandLog.class); } public List getDpsLandsByTime(int begin, int end, Date beginDate,Date endDate) { return find(new Query(Criteria.where.gte.lte.limit.skip, DpsLand.class); } 

注意:BooleanClause.Occur[]数组,它表示多个条件之间的关系: 

3.1.两种方案

    通过关键字的检索,当lucene返回多条记录的时候,往往一个页面是无法容纳所有检索结果的,这自然而然就该分页了。我这里给出两种方案,这两种方法我都是用过。

    第一种方法,就是讲检索结果全部封装在一个Collection中,例如List中,将这个结果传到前台,如jsp页面。然后在这个list中进行分页显示;

    第二种方法,是使用lucene自带的分页工具public TopDocs topDocs(int start,int howMany)。

    我认为,第一种方法不涉及二次查询,这样的话就避免了在查询上的浪费。但是当检索的结果数据量很大,这样一次性传输这么多数据到客户端,而用户检索后得到的结果往往只会查看第一页的内容,很少去查看第二页、第三页以及后面的内容,所以一次性将全部结果传到前台,这样的浪费是很大的。

    第二种方法,虽然每次翻页都意味着一次查询,表面上浪费了资源,但是由于lucene的高效,这样的浪费对整个系统的影响是微乎其微的,但是这个方法避免了方法一中的缺陷。

查询字段不存在的数据 -----关键字---not

BooleanClause.Occur.MUST表示and, feedom.net 

3.2.分页实现

[java] view plaincopy

  1. /** 
  2.      * 对搜索返回的前n条结果进行分页显示 
  3.      * @param keyWord       查询关键词 
  4.      * @param pageSize      每页显示记录数 
  5.      * @param currentPage   当前页  
  6.      */  
  7.     public void paginationQuery(String keyWord,int pageSize,int currentPage) throws ParseException, CorruptIndexException, IOException {  
  8.         String[] fields = {"title","content"};  
  9.         QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_36,fields,analyzer);  
  10.         Query query = queryParser.parse(keyWord);  
  11.            
  12.         IndexReader indexReader  = IndexReader.open(directory);  
  13.         IndexSearcher indexSearcher = new IndexSearcher(indexReader);  
  14.            
  15.         //TopDocs 搜索返回的结果  
  16.         TopDocs topDocs = indexSearcher.search(query, 100);//只返回前100条记录  
  17.         int totalCount = topDocs.totalHits; // 搜索结果总数量  
  18.         ScoreDoc[] scoreDocs = topDocs.scoreDocs; // 搜索返回的结果集合  
  19.            
  20.         //查询起始记录位置  
  21.         int begin = pageSize * (currentPage - 1) ;  
  22.         //查询终止记录位置  
  23.         int end = Math.min(begin + pageSize, scoreDocs.length);  
  24.            
  25.         //进行分页查询  
  26.         for(int i=begin;i<end;i++) {  
  27.             int docID = scoreDocs[i].doc;  
  28.             Document doc = indexSearcher.doc(docID);  
  29.             int id = NumericUtils.prefixCodedToInt(doc.get("id"));  
  30.             String title = doc.get("title");  
  31.             System.out.println("id is : "+id);  
  32.             System.out.println("title is : "+title);  
  33.         }     
  34.     }  
public List getGoodsDetails2 { Query query = new Query(); query.addCriteria(Criteria.where); return find(query.limit.skip,GoodsDetail.class); } 

BooleanClause.Occur.MUST_NOT表示not, 54com.cn 

4.高亮检索结果

    针对检索结果的高亮实现方法,在lucene中提供了响应的工具,这里使用lucene-highlighter-3.6.2.jar来实现对检索结果的高亮显示。

[java] view plaincopy

  1. public void search(String fieldName, String keyword)throws CorruptIndexException, IOException, ParseException {  
  2.     searcher = new IndexSearcher(indexPath);  
  3.     QueryParser queryParse = new QueryParser(fieldName, analyzer); // 构造QueryParser,解析用户输入的检索关键字  
  4.     Query query = queryParse.parse(keyword);  
  5.     Hits hits = searcher.search(query);  
  6.     for (int i = 0; i < hits.length(); i++) {  
  7.         Document doc = hits.doc(i);  
  8.         String text = doc.get(fieldName);  
  9.         SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");  
  10.         Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));  
  11.         highlighter.setTextFragmenter(new SimpleFragmenter(text.length()));  
  12.         if (text != null) {  
  13.             TokenStream tokenStream = analyzer.tokenStream(fieldName,new StringReader(text));  
  14.             String highLightText = highlighter.getBestFragment(tokenStream,text);  
  15.             System.out.println("高亮显示第 " + (i + 1) + " 条检索结果如下所示:");  
  16.             System.out.println(highLightText);  
  17.         }  
  18.     }  
  19.     searcher.close();  
  20. }  

上文的一行判断语句很重要:if(text != null),如果text为空,那么显示结果不但没有被高亮,而且得到的原始结果也会被过滤。可以再代码中加上,如果text==null,则让将原始检索结果赋给text,从而将结果显示出来。

 

查询字段不为空的数据 -----关键字---ne

BooleanClause.Occur.SHOULD表示or. 

5.检索结果的评分

    lucene的评分是有一套自己的机制的,输入某一个关键字,lucene会对命中的记录进行评分,默认情况下,分数越高的结果会排在结果的越前面。如果在创建索引的时候,没有对某个域进行加权,那么默认分数的上限是5分,如果有对域做加权,检索结果的评分可能会出现大于5分的情况。

    我们可以使用explain()来看看lucene对检索结果的评分情况:

[java] view plaincopy

  1. //评分  
  2. Explanation explanation = indexSearcher.explain(query, docID);  
  3. System.out.println(explanation.toString());  

在后台打印出来的信息如下:

[plain] view plaincopy

  1. 2.4342022 = (MATCH) weight(name:books in 71491), product of:  
  2.        0.2964393 = queryWeight(name:books), product of:  
  3.          8.21147 = idf(docFreq=109, maxDocs=149037)  
  4.          0.036100637 = queryNorm  
Criteria.where.ne 

--------------------------------------------------------------------------------------------------------- 
多个关键字直接的关系是或,所以直接使用多域搜索对象查询出来的结果就是这样。 
更灵活的控制方式为: 

查询或语句:a || b ----- 关键字---orOperator

Java代码 

Criteria criteria = new Criteria(); criteria.orOperator(Criteria.where,Criteria.where; 

 图片 3)

查询且语句:a && b ----- 关键字---and

  1. BooleanQuery booleanQuery = new BooleanQuery();   
  2.   
  3. QueryParser parser = new QueryParser("title",分词器);   
  4. Query titleQuery = parser .parser("中国人民共和国");  
  5. booleanQuery.add(titleQuery,....SHOULD);  
  6.   
  7. QueryParser parser = new QueryParser("content",分词器);   
  8. Query contentQuery = parser .parser("中国人民共和国");  
  9. booleanQuery.add(contentQuery ,....SHOULD);   
Criteria criteria = new Criteria(); criteria.and; criteria.and; Query query = new Query; long totalCount = this.mongoTemplate.count;

-------------------------------------------------------------------------------------------------- 

查询一个属性的子属性,例如:查下面数据的key2.keyA的语句

Java代码 

var s = { key1: value1, key2: { keyA: valueA, keyB: valueB } }; @Query("{'key2.keyA':?0}") List findAllBykeyA; 

 图片 4)

  1. 查询数量:----- 关键字---count

    public long getPageInfosCount(List conditions) { Query query = new Query(); if (conditions != null && conditions.size { for (Condition condition : conditions) { query.addCriteria(Criteria.where.is); } } return count(query, PageInfo.class); }

  1. package com.lucene.search;  
  2. import org.apache.lucene.analysis.standard.StandardAnalyzer;   
  3. import org.apache.lucene.document.Document;   
  4. import org.apache.lucene.document.Field;  
  5. import org.apache.lucene.index.IndexWriter;  
  6. import org.apache.lucene.queryParser.MultiFieldQueryParser;  
  7. import org.apache.lucene.search.BooleanClause;  
  8. import org.apache.lucene.search.Hits; import org.apache.lucene.search.IndexSearcher;   
  9. import org.apache.lucene.search.MultiSearcher;   
  10. import org.apache.lucene.search.Query;   
  11. public class Multisearcher {   
  12. private static String INDEX_STORE_PATH1 = "C:\multi\1"; private static String INDEX_STORE_PATH2 = "C:\multi\2";   
  13. public static void main(String[] args) throws Exception {   
  14. Multisearcher.multisearcher();   
  15. }   
  16. public static void multisearcher() throws Exception {   
  17. IndexWriter writer = new IndexWriter(INDEX_STORE_PATH1, new StandardAnalyzer(), true);   
  18. writer.setUseCompoundFile(false);   
  19. Document doc1 = new Document();   
  20. Field f1 = new Field("bookname", "钢铁是怎样炼成的", Field.Store.YES, Field.Index.TOKENIZED);   
  21. Field f11 = new Field("price", "20.5", Field.Store.YES, Field.Index.UN_TOKENIZED);   
  22. doc1.add(f1); doc1.add(f11);   
  23. Document doc2 = new Document();   
  24. Field f2 = new Field("bookname", "钢铁战士", Field.Store.YES, Field.Index.TOKENIZED);   
  25. Field f22 = new Field("price", "18.4", Field.Store.YES, Field.Index.UN_TOKENIZED);   
  26. doc2.add(f2);   
  27. doc2.add(f22);   
  28. Document doc3 = new Document();   
  29. Field f3 = new Field("bookname", "钢和铁是两种不同的元素", Field.Store.YES, Field.Index.TOKENIZED);   
  30. Field f33 = new Field("price", "7.6", Field.Store.YES, Field.Index.UN_TOKENIZED);   
  31. doc3.add(f3);   
  32. doc3.add(f33);   
  33. writer.addDocument(doc1);   
  34. writer.addDocument(doc2);   
  35. writer.addDocument(doc3);   
  36. writer.close(); //创建第二个索引器;   
  37. IndexWriter writer2 = new IndexWriter(INDEX_STORE_PATH2, new StandardAnalyzer(), true);   
  38. writer2.setUseCompoundFile(false);   
  39. Document doc4 = new Document();   
  40. Field f4 = new Field("bookname", "钢要比铁有更多的元素", Field.Store.YES, Field.Index.TOKENIZED);   
  41. Field f44 = new Field("price", "22.5", Field.Store.YES, Field.Index.UN_TOKENIZED);   
  42. doc4.add(f4); doc4.add(f44);   
  43. Document doc5 = new Document();   
  44. Field f5 = new Field("bookname", "钢和铁是两种重要的金属", Field.Store.YES, Field.Index.TOKENIZED);   
  45. Field f55 = new Field("price", "15.9", Field.Store.YES, Field.Index.UN_TOKENIZED);   
  46. doc5.add(f5); doc5.add(f55); Document doc6 = new Document();   
  47. Field f6 = new Field("bookname", "钢铁是两种重要的金属", Field.Store.YES, Field.Index.TOKENIZED);   
  48. Field f66 = new Field("price", "19.00", Field.Store.YES, Field.Index.UN_TOKENIZED);   
  49. doc6.add(f6);   
  50. doc6.add(f66);   
  51. writer2.addDocument(doc4);   
  52. writer2.addDocument(doc5);   
  53. writer2.addDocument(doc6);   
  54. writer2.close();   
  55. String query1 = "钢";   
  56. String query2 = "[10 TO 20]";//注意格式:中括号还有关键字TO是大写的   
  57. String[] queries = { query1, query2 }; //指定两个域  
  58. Field String field1 = "bookname";   
  59. String field2 = "price";   
  60. String[] fields = { field1, field2 }; //指定查询字句之间的关系   
  61. BooleanClause.Occur[] clauses = {   
  62. BooleanClause.Occur.MUST, BooleanClause.Occur.MUST   
  63. }; //转成多域查询  
  64. MultiFieldQuery Query q = MultiFieldQueryParser.parse(queries, fields, clauses, new StandardAnalyzer()); //打印Query的内容 System.out.println(q.toString()); //创建两个IndexSearcher,以实现在多个索引目录进行查询   
  65. IndexSearcher searcher1 = new IndexSearcher(INDEX_STORE_PATH1);   
  66. IndexSearcher searcher2 = new IndexSearcher(INDEX_STORE_PATH2);   
  67. IndexSearcher[] searchers = { searcher1, searcher2 }; //使用MultiSearcher进行多域搜索   
  68. MultiSearcher searcher = new MultiSearcher(searchers);   
  69. Hits hits = searcher.search(q);   
  70. for (int i = 0; i < hits.length(); i++) {   
  71. System.out.println(hits.doc(i));   
  72. }   
  73. }  
  74. }  

查找包含在某个集合范围:----- 关键字---in

------------------------------------------------------------------------------------------------------------------------------------------ 
默认情况下,IndexSearcher类的search方法返回查询结果时,是按文档的分值排序的,可以使用重载的search方法对结果排序 

Criteria criteria = new Criteria(); Object [] o = new Object[]{0, 1, 2}; //包含所有 criteria.and; Query query = new Query; query.with(new Sort(new Sort.Order(Direction.ASC, "type"))).with(new Sort(new Sort.Order(Direction.ASC, "title"))); List list = this.mongoTemplate.find(query, WidgetMonitor.class); 

IndexSearcher.search(Query,Sort); 

  1. 更新一条数据的一个字段:

    public WriteResult updateTime { String id = pageUrl.getId(); return updateFirst(new Query.is,Update.update("updateTime", pageUrl.getUpdateTime; }

  2. 更新一条数据的多个字段:

    //调用更新 private void updateProcessLandLog(ProcessLandLog processLandLog, int crawlResult) { List fields = new ArrayList(); List values = new ArrayList(); fields.add; fields.add; fields.add; values.add; values.add; values.add(Calendar.getInstance; processLandLogReposity.updateProcessLandLog(processLandLog, fields, values); } //更新 public void updateProcessLandLog(ProcessLandLog land, List fields,List values) { Update update = new Update(); int size = fields.size(); for(int i = 0 ; i < size; i++){ String field = fields.get; Object value = values.get; update.set; } updateFirst(new Query.is, update,ProcessLandLog.class); }

    public void deleteObject(Class clazz,String id) { remove(new Query.is; }

    //插入一条数据 public void saveObject { insert; } //插入多条数据 public void saveObjects { for{ insert; } }

new Sort() 和 Sort.RELEVANCE,以及null一样,采用默认排序,要定义排序字段,方法是将字段传入Sort对象 

本文由杏彩发布,转载请注明来源

关键词: