mirror of
https://github.com/Alfresco/SearchServices.git
synced 2026-09-16 18:12:56 +00:00
SEARCH-251: Search by FINGERPRINT DBID and noderef
This commit is contained in:
+46
-14
@@ -20,17 +20,20 @@
|
||||
package org.alfresco.solr.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.*;
|
||||
|
||||
import org.alfresco.repo.search.adaptor.lucene.QueryConstants;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.solr.AlfrescoCoreAdminHandler;
|
||||
import org.alfresco.solr.AlfrescoSolrDataModel;
|
||||
import org.alfresco.solr.SolrInformationServer;
|
||||
import org.alfresco.solr.content.SolrContentStore;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.index.IndexableField;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.ScoreDoc;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.search.TopDocs;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.apache.solr.common.SolrInputField;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
@@ -38,6 +41,7 @@ import org.apache.solr.core.CoreContainer;
|
||||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.handler.component.*;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.util.plugin.SolrCoreAware;
|
||||
|
||||
/**
|
||||
@@ -67,22 +71,50 @@ public class FingerPrintComponent extends SearchComponent implements SolrCoreAwa
|
||||
|
||||
NamedList response = responseBuilder.rsp.getValues();
|
||||
String id = responseBuilder.req.getParams().get("id");
|
||||
NamedList fingerPrint = new NamedList();
|
||||
SolrInputDocument solrDoc = solrContentStore.retrieveDocFromSolrContentStore(AlfrescoSolrDataModel.getTenantId(TenantService.DEFAULT_DOMAIN), Long.parseLong(id));
|
||||
|
||||
if(solrDoc != null) {
|
||||
SolrInputField mh = solrDoc.getField("MINHASH");
|
||||
if(mh != null) {
|
||||
Collection col = mh.getValues();
|
||||
List l = new ArrayList();
|
||||
l.addAll(col);
|
||||
fingerPrint.add("MINHASH", l);
|
||||
if(id.contains("-")) {
|
||||
long dbid = fetchDBID(id, responseBuilder.req.getSearcher());
|
||||
if(dbid > -1) {
|
||||
id = Long.toString(dbid);
|
||||
} else {
|
||||
id = null;
|
||||
}
|
||||
}
|
||||
|
||||
NamedList fingerPrint = new NamedList();
|
||||
if(id != null) {
|
||||
SolrInputDocument solrDoc = solrContentStore.retrieveDocFromSolrContentStore(AlfrescoSolrDataModel.getTenantId(TenantService.DEFAULT_DOMAIN), Long.parseLong(id));
|
||||
if (solrDoc != null) {
|
||||
SolrInputField mh = solrDoc.getField("MINHASH");
|
||||
if (mh != null) {
|
||||
Collection col = mh.getValues();
|
||||
List l = new ArrayList();
|
||||
l.addAll(col);
|
||||
fingerPrint.add("MINHASH", l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response.add("fingerprint", fingerPrint);
|
||||
}
|
||||
|
||||
private long fetchDBID(String UUID, SolrIndexSearcher searcher) throws IOException {
|
||||
String query = "workspace://SpacesStore/"+UUID;
|
||||
TermQuery q = new TermQuery(new Term(QueryConstants.FIELD_LID, query));
|
||||
TopDocs docs = searcher.search(q, 1);
|
||||
Set<String> fields = new HashSet();
|
||||
fields.add(QueryConstants.FIELD_DBID);
|
||||
if(docs.totalHits == 1) {
|
||||
ScoreDoc scoreDoc = docs.scoreDocs[0];
|
||||
Document doc = searcher.doc(scoreDoc.doc, fields);
|
||||
IndexableField dbidField = doc.getField(QueryConstants.FIELD_DBID);
|
||||
return dbidField.numericValue().longValue();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
private SolrContentStore getContentStore(SolrQueryRequest req)
|
||||
{
|
||||
if(req.getSearcher() != null)
|
||||
|
||||
+44
-17
@@ -78,6 +78,7 @@ import org.alfresco.util.Pair;
|
||||
import org.alfresco.util.SearchLanguageConversion;
|
||||
import org.antlr.misc.OrderedHashSet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.solr.client.solrj.SolrRequest;
|
||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -99,17 +100,8 @@ import org.apache.lucene.index.IndexableField;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.queryparser.classic.ParseException;
|
||||
import org.apache.lucene.queryparser.classic.QueryParser;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.BooleanQuery.Builder;
|
||||
import org.apache.lucene.search.ConstantScoreQuery;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.search.MultiTermQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.RegexpQuery;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.search.TermRangeQuery;
|
||||
import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
|
||||
import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper.TopTermsSpanBooleanQueryRewrite;
|
||||
import org.apache.lucene.search.spans.SpanNearQuery;
|
||||
@@ -134,6 +126,7 @@ import org.apache.solr.handler.component.ShardHandlerFactory;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.apache.solr.schema.SchemaField;
|
||||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.update.DocumentBuilder;
|
||||
import org.apache.solr.update.UpdateShardHandlerConfig;
|
||||
import org.jaxen.saxpath.SAXPathException;
|
||||
@@ -690,7 +683,7 @@ public class Solr4QueryParser extends QueryParser implements QueryConstants
|
||||
{
|
||||
String[] parts = queryText.split("_");
|
||||
Collection values = null;
|
||||
long nodeId = Long.parseLong(parts[0]);
|
||||
String nodeId = parts[0];
|
||||
|
||||
JSONObject json = (JSONObject)request.getContext().get(AbstractQParser.ALFRESCO_JSON);
|
||||
String fingerPrint = null;
|
||||
@@ -712,13 +705,25 @@ public class Solr4QueryParser extends QueryParser implements QueryConstants
|
||||
json = new JSONObject();
|
||||
}
|
||||
|
||||
|
||||
//Is the fingerprint in the local SolrContentStore
|
||||
if(values == null) {
|
||||
SolrInputDocument solrDoc = solrContentStore.retrieveDocFromSolrContentStore(AlfrescoSolrDataModel.getTenantId(TenantService.DEFAULT_DOMAIN), nodeId);
|
||||
if (solrDoc != null) {
|
||||
SolrInputField mh = solrDoc.getField("MINHASH");
|
||||
if (mh != null) {
|
||||
values = mh.getValues();
|
||||
long dbid = -1;
|
||||
//Do we have a UUID or DBID
|
||||
if(nodeId.contains("-")) {
|
||||
//It's a UUID. We need the DBID.
|
||||
dbid = fetchDBID(nodeId);
|
||||
} else {
|
||||
dbid = Long.parseLong(nodeId);
|
||||
}
|
||||
|
||||
if(dbid > -1) {
|
||||
SolrInputDocument solrDoc = solrContentStore.retrieveDocFromSolrContentStore(AlfrescoSolrDataModel.getTenantId(TenantService.DEFAULT_DOMAIN), dbid);
|
||||
if (solrDoc != null) {
|
||||
SolrInputField mh = solrDoc.getField("MINHASH");
|
||||
if (mh != null) {
|
||||
values = mh.getValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -728,6 +733,7 @@ public class Solr4QueryParser extends QueryParser implements QueryConstants
|
||||
{
|
||||
//we are in distributed mode
|
||||
//Fetch the fingerPrint from the shards.
|
||||
//The UUID and DBID will work both work for method call.
|
||||
values = fetchFingerPrint(shards, nodeId);
|
||||
}
|
||||
|
||||
@@ -772,7 +778,26 @@ public class Solr4QueryParser extends QueryParser implements QueryConstants
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private Collection fetchFingerPrint(String shards, long nodeId) {
|
||||
|
||||
private long fetchDBID(String UUID) throws IOException {
|
||||
SolrIndexSearcher searcher = request.getSearcher();
|
||||
String query = UUID.startsWith("workspace") ? UUID : "workspace://SpacesStore/"+UUID;
|
||||
TermQuery q = new TermQuery(new Term(FIELD_LID, query));
|
||||
TopDocs docs = searcher.search(q, 1);
|
||||
Set<String> fields = new HashSet();
|
||||
fields.add(FIELD_DBID);
|
||||
if(docs.totalHits == 1) {
|
||||
ScoreDoc scoreDoc = docs.scoreDocs[0];
|
||||
Document doc = searcher.doc(scoreDoc.doc, fields);
|
||||
IndexableField dbidField = doc.getField(FIELD_DBID);
|
||||
return dbidField.numericValue().longValue();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
private Collection fetchFingerPrint(String shards, String nodeId) {
|
||||
shards = shards.replace(",", "|");
|
||||
List<String> urls = ((HttpShardHandlerFactory)shardHandlerFactory).makeURLList(shards);
|
||||
ExecutorService executorService = null;
|
||||
@@ -781,7 +806,7 @@ public class Solr4QueryParser extends QueryParser implements QueryConstants
|
||||
try {
|
||||
executorService = Executors.newCachedThreadPool();
|
||||
for (String url : urls) {
|
||||
futures.add(executorService.submit(new FingerPrintFetchTask(url, Long.toString(nodeId))));
|
||||
futures.add(executorService.submit(new FingerPrintFetchTask(url, nodeId)));
|
||||
}
|
||||
|
||||
for (Future<Collection> future : futures) {
|
||||
@@ -800,6 +825,8 @@ public class Solr4QueryParser extends QueryParser implements QueryConstants
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private class FingerPrintFetchTask implements Callable<Collection> {
|
||||
private String url;
|
||||
private String id;
|
||||
|
||||
+67
@@ -232,5 +232,72 @@ public class AlfrescoSolrFingerprintTest extends AbstractAlfrescoSolrTests
|
||||
"//result/doc[2]/long[@name='DBID'][.='"+node2.getId()+"']",
|
||||
"//result/doc[3]/long[@name='DBID'][.='"+node3.getId()+"']",
|
||||
"//result/doc[4]/long[@name='DBID'][.='"+node1.getId()+"']");
|
||||
|
||||
//Test nodeRef
|
||||
|
||||
params = new ModifiableSolrParams();
|
||||
params.add("q", "FINGERPRINT:" + nodeMetaData1.getNodeRef().getId()); //Query for an id in the content field. The node id is automatically populated into the content field by test framework
|
||||
params.add("qt", "/afts");
|
||||
params.add("fl", "DBID,score");
|
||||
params.add("start", "0");
|
||||
params.add("rows", "6");
|
||||
|
||||
req = areq(params, null);
|
||||
assertQ(req, "*[count(//doc)=4]",
|
||||
"//result/doc[1]/long[@name='DBID'][.='" + node1.getId() + "']",
|
||||
"//result/doc[2]/long[@name='DBID'][.='" + node3.getId() + "']",
|
||||
"//result/doc[3]/long[@name='DBID'][.='" + node2.getId() + "']",
|
||||
"//result/doc[4]/long[@name='DBID'][.='" + node4.getId() + "']");
|
||||
|
||||
params = new ModifiableSolrParams();
|
||||
params.add("q", "FINGERPRINT:" + nodeMetaData1.getNodeRef().getId() + "_70"); //Query for an id in the content field. The node id is automatically populated into the content field by test framework
|
||||
params.add("qt", "/afts");
|
||||
params.add("fl","DBID,score");
|
||||
params.add("start", "0");
|
||||
params.add("rows", "6");
|
||||
req = areq(params, null);
|
||||
assertQ(req, "*[count(//doc)= 2]",
|
||||
"//result/doc[1]/long[@name='DBID'][.='"+node1.getId()+"']",
|
||||
"//result/doc[2]/long[@name='DBID'][.='"+node3.getId()+"']");
|
||||
|
||||
params = new ModifiableSolrParams();
|
||||
params.add("q", "FINGERPRINT:" + nodeMetaData1.getNodeRef().getId()+"_45"); //Query for an id in the content field. The node id is automatically populated into the content field by test framework
|
||||
params.add("qt", "/afts");
|
||||
params.add("fl","DBID,score");
|
||||
params.add("start", "0");
|
||||
params.add("rows", "6");
|
||||
req = areq(params, null);
|
||||
assertQ(req, "*[count(//doc)= 3]",
|
||||
"//result/doc[1]/long[@name='DBID'][.='"+node1.getId()+"']",
|
||||
"//result/doc[2]/long[@name='DBID'][.='"+node3.getId()+"']",
|
||||
"//result/doc[3]/long[@name='DBID'][.='"+node2.getId()+"']");
|
||||
|
||||
params = new ModifiableSolrParams();
|
||||
params.add("q", "FINGERPRINT:" + nodeMetaData1.getNodeRef().getId()+"_30");
|
||||
params.add("qt", "/afts");
|
||||
params.add("fl","DBID,score");
|
||||
params.add("start", "0");
|
||||
params.add("rows", "6");
|
||||
req = areq(params, null);
|
||||
assertQ(req, "*[count(//doc)= 4]",
|
||||
"//result/doc[1]/long[@name='DBID'][.='"+node1.getId()+"']",
|
||||
"//result/doc[2]/long[@name='DBID'][.='"+node3.getId()+"']",
|
||||
"//result/doc[3]/long[@name='DBID'][.='"+node2.getId()+"']",
|
||||
"//result/doc[4]/long[@name='DBID'][.='"+node4.getId()+"']");
|
||||
|
||||
|
||||
params = new ModifiableSolrParams();
|
||||
params.add("q", "FINGERPRINT:" + nodeMetaData4.getNodeRef().getId());
|
||||
params.add("qt", "/afts");
|
||||
params.add("fl","DBID,score");
|
||||
params.add("start", "0");
|
||||
params.add("rows", "6");
|
||||
req = areq(params, null);
|
||||
assertQ(req, "*[count(//doc)= 4]",
|
||||
"//result/doc[1]/long[@name='DBID'][.='"+node4.getId()+"']",
|
||||
"//result/doc[2]/long[@name='DBID'][.='"+node2.getId()+"']",
|
||||
"//result/doc[3]/long[@name='DBID'][.='"+node3.getId()+"']",
|
||||
"//result/doc[4]/long[@name='DBID'][.='"+node1.getId()+"']");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+71
@@ -243,6 +243,77 @@ public class DistributedAlfrescoSolrFingerPrintTest extends AbstractAlfrescoDist
|
||||
doc2 = docs.get(2);
|
||||
dbid2 = (long)doc2.getFieldValue("DBID");
|
||||
assertTrue(dbid2 == node2.getId());
|
||||
|
||||
|
||||
response = query(getDefaultTestClient(), true,
|
||||
"{\"locales\":[\"en\"], \"templates\": [{\"name\":\"t1\", \"template\":\"%cm:content\"}], \"authorities\": [\"joel\"], \"tenants\": []}",
|
||||
params("q", "FINGERPRINT:"+nodeMetaData1.getNodeRef().getId(),
|
||||
"qt", "/afts",
|
||||
"shards.qt", "/afts",
|
||||
"start", "0",
|
||||
"fl","DBID,score",
|
||||
"rows", "100"));
|
||||
|
||||
docs = response.getResults();
|
||||
assertTrue(docs.getNumFound() == 4);
|
||||
doc0 = docs.get(0);
|
||||
dbid0 = (long)doc0.getFieldValue("DBID");
|
||||
assertTrue(dbid0 == node1.getId());
|
||||
|
||||
doc1 = docs.get(1);
|
||||
dbid1 = (long)doc1.getFieldValue("DBID");
|
||||
assertTrue(dbid1 == node3.getId());
|
||||
|
||||
doc2 = docs.get(2);
|
||||
dbid2 = (long)doc2.getFieldValue("DBID");
|
||||
assertTrue(dbid2 == node2.getId());
|
||||
|
||||
doc3 = docs.get(3);
|
||||
dbid3 = (long)doc3.getFieldValue("DBID");
|
||||
assertTrue(dbid3 == node4.getId());
|
||||
|
||||
response = query(getDefaultTestClient(), true,
|
||||
"{\"locales\":[\"en\"], \"templates\": [{\"name\":\"t1\", \"template\":\"%cm:content\"}], \"authorities\": [\"joel\"], \"tenants\": []}",
|
||||
params("q", "FINGERPRINT:" + nodeMetaData1.getNodeRef().getId() +"_70",
|
||||
"qt", "/afts",
|
||||
"shards.qt", "/afts",
|
||||
"start", "0",
|
||||
"fl", "DBID,score",
|
||||
"rows", "100"));
|
||||
|
||||
docs = response.getResults();
|
||||
assertTrue(docs.getNumFound() == 2);
|
||||
doc0 = docs.get(0);
|
||||
dbid0 = (long)doc0.getFieldValue("DBID");
|
||||
assertTrue(dbid0 == node1.getId());
|
||||
|
||||
doc1 = docs.get(1);
|
||||
dbid1 = (long)doc1.getFieldValue("DBID");
|
||||
assertTrue(dbid1 == node3.getId());
|
||||
|
||||
response = query(getDefaultTestClient(), true,
|
||||
"{\"locales\":[\"en\"], \"templates\": [{\"name\":\"t1\", \"template\":\"%cm:content\"}], \"authorities\": [\"joel\"], \"tenants\": []}",
|
||||
params("q", "FINGERPRINT:" + nodeMetaData1.getNodeRef().getId() +"_45",
|
||||
"qt", "/afts",
|
||||
"shards.qt", "/afts",
|
||||
"start", "0",
|
||||
"fl", "DBID,score",
|
||||
"rows", "100"));
|
||||
|
||||
docs = response.getResults();
|
||||
assertTrue(docs.getNumFound() == 3);
|
||||
doc0 = docs.get(0);
|
||||
dbid0 = (long)doc0.getFieldValue("DBID");
|
||||
assertTrue(dbid0 == node1.getId());
|
||||
|
||||
doc1 = docs.get(1);
|
||||
dbid1 = (long)doc1.getFieldValue("DBID");
|
||||
assertTrue(dbid1 == node3.getId());
|
||||
|
||||
doc2 = docs.get(2);
|
||||
dbid2 = (long)doc2.getFieldValue("DBID");
|
||||
assertTrue(dbid2 == node2.getId());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user