问题
I am currently going through Hibernate Search 4.1
I have one Table (file_data,fileName) I want to create one query like file_data:XYZ and fileName:abc.pdf
How to perform this query? Below I have try to make query for this..
Query luceQry3 = queryBuilder
.bool()
.must(
queryBuilder
.bool()
.must(
queryBuilder.
keyword().
onField("file_data")
.ignoreFieldBridge()
.matching("HDFC")
.createQuery()).createQuery())
.must(queryBuilder.
keyword().
onField("fileName")
.ignoreFieldBridge()
.matching("0_119.pdf")
.createQuery()).createQuery();
but this query and
Query luceneQry = queryBuilder.keyword().
onField("file_data").ignoreFieldBridge().
matching("HDFC").
createQuery();
returns same result. I want to use AND operator so that I can minimize the query result.
------- My Entity Mapping is given below-----
@Entity
@Table(name="file_upload")
@Indexed
@Analyzer(impl = org.apache.lucene.analysis.standard.StandardAnalyzer.class)
public class FileUploadModel implements Serializable {
private static final long serialVersionUID = -5376124674712529869L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Field(index=Index.YES,store=Store.NO)
@DocumentId
private Integer file_upload_id;
@Column(name="file_name")
@Field(index=Index.YES,store=Store.YES)
private String fileName;
@IndexedEmbedded
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="user_id")
private User user;
@Column(name="file_type")
private String file_type;
@Column(name="file_data")
@Lob
@Field(index=Index.YES,store=Store.NO,name="file_data")
@FieldBridge(impl=com.test.documentsearch.core.BlobToString.class )
private byte[] file_data;
public Integer getFile_upload_id() {
return file_upload_id;
}
public void setFile_upload_id(Integer file_upload_id) {
this.file_upload_id = file_upload_id;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getFile_type() {
return file_type;
}
public void setFile_type(String file_type) {
this.file_type = file_type;
}
public byte[] getFile_data() {
return file_data;
}
public void setFile_data(byte[] file_data) {
this.file_data = file_data;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}
I have used FieldBridge...
public class BlobToString extends StringBridge {
@Override
public String objectToString(Object object) {
try
{
byte[] byteData = ((String)object).getBytes();
MagicMatch match = Magic.getMagicMatch((byte[])byteData);
String mimeType = match.getMimeType();
String extn = match.getExtension();
if(mimeType.equalsIgnoreCase("image/jpeg"))
{
}
else if(mimeType.equalsIgnoreCase("application/pdf"))
{
COSDocument cd = null;
ByteArrayInputStream bais =null;
try
{
bais = new ByteArrayInputStream((byte[])object);
PDFParser pdf = new PDFParser(bais);
pdf.parse();
cd = pdf.getDocument();
PDFTextStripper stripper = new PDFTextStripper();
String text = stripper.getText(new PDDocument(cd));
cd.close();
bais.close();
return text;
}
catch(Exception ex)
{
cd.close();
bais.close();
ex.printStackTrace();
}
}
else if(mimeType.equalsIgnoreCase("application/rtf") || mimeType.equalsIgnoreCase("text/rtf"))
{
ByteArrayInputStream bais = new ByteArrayInputStream((byte[])object);
RTFEditorKit kit = new RTFEditorKit();
Document doc = kit.createDefaultDocument();
kit.read(bais, doc, 0);
bais.close();
return doc.getText(0,doc.getLength());
}
else if(mimeType.equalsIgnoreCase("application/msword"))
{
StringBuilder _result = new StringBuilder();
try {
ByteArrayInputStream bais = new ByteArrayInputStream((byte[]) object);
WordExtractor extractor = new WordExtractor(bais);
String wordText = extractor.getText();
bais.close();
return wordText;
} catch (IOException ex) {
ex.printStackTrace();
}
}
else if(mimeType.equalsIgnoreCase("application/vnd.ms-excel"))
{
StringBuilder _result = new StringBuilder();
try {
ByteArrayInputStream bais = new ByteArrayInputStream((byte[]) object);
WordExtractor extractor = new WordExtractor(bais);
String wordText = extractor.getText();
bais.close();
return wordText;
} catch (IOException ex) {
ex.printStackTrace();
}
}
System.out.println(mimeType);
return null;
}catch(Exception ex)
{
ex.printStackTrace();
return ex.getMessage();
}
}
}
回答1:
Make two queries
Query query1=queryBuilder.keyword().
onField("file_data").ignoreFieldBridge().
matching("HDFC").
createQuery();
Query query2=queryBuilder.keyword().
onField("fileName").ignoreFieldBridge().
matching("abc.pdf").
createQuery();
Add them in a list :
listOfQuery.add(query1);
listOfQuery.add(query2);
Then build a final query as
Query finalLuceneQuery=new BooleanQuery();
for (Query query : listOfQuery) {
finalLuceneQuery.add(query, BooleanClause.Occur.MUST);
}
fullTextQuery = fullTextSession.createFullTextQuery(finalLuceneQuery, <Youclass>.class);
This will work for you.
来源:https://stackoverflow.com/questions/15926304/hibernate-search-lucene-and-operator-query