use of org.apache.solr.common.SolrInputField in project lucene-solr by apache.
the class TestUpdateRequestCodec method compareDocs.
private void compareDocs(String m, SolrInputDocument expectedDoc, SolrInputDocument actualDoc) {
for (String s : expectedDoc.getFieldNames()) {
SolrInputField expectedField = expectedDoc.getField(s);
SolrInputField actualField = actualDoc.getField(s);
Object expectedVal = expectedField.getValue();
Object actualVal = actualField.getValue();
if (expectedVal instanceof Set && actualVal instanceof Collection) {
// unmarshaled documents never contain Sets, they are just a
// List in an arbitrary order based on what the iterator of
// hte original Set returned, so we need a comparison that is
// order agnostic.
actualVal = new HashSet((Collection) actualVal);
m += " (Set comparison)";
}
Assert.assertEquals(m + " diff values for field: " + s, expectedVal, actualVal);
}
}
use of org.apache.solr.common.SolrInputField in project lucene-solr by apache.
the class TestInPlaceUpdatesStandalone method checkReplay.
/**
* Executes a sequence of commands against Solr, while tracking the expected value of a specified
* <code>valField</code> Long field (presumably that only uses docvalues) against an in memory model
* maintained in parallel (for the purpose of testing the correctness of in-place updates..
*
* <p>
* A few restrictions are placed on the {@link SolrInputDocument}s that can be included when using
* this method, in order to keep the in-memory model management simple:
* </p>
* <ul>
* <li><code>id</code> must be uniqueKey field</li>
* <li><code>id</code> may have any FieldType, but all values must be parsable as Integers</li>
* <li><code>valField</code> must be a single valued field</li>
* <li>All values in the <code>valField</code> must either be {@link Number}s, or Maps containing
* atomic updates ("inc" or "set") where the atomic value is a {@link Number}</li>
* </ul>
*
* @param valField the field to model
* @param commands A sequence of Commands which can either be SolrInputDocuments
* (regular or containing atomic update Maps)
* or one of the {@link TestInPlaceUpdatesStandalone#HARDCOMMIT} or {@link TestInPlaceUpdatesStandalone#SOFTCOMMIT} sentinal objects.
*/
public void checkReplay(final String valField, Object... commands) throws Exception {
HashMap<Integer, DocInfo> model = new LinkedHashMap<>();
HashMap<Integer, DocInfo> committedModel = new LinkedHashMap<>();
// by default, we only check the committed model after a commit
// of if the number of total commands is relatively small.
//
// (in theory, there's no reason to check the committed model unless we know there's been a commit
// but for smaller tests the overhead of doing so is tiny, so we might as well)
//
// if some test seed fails, and you want to force the committed model to be checked
// after every command, just temporaribly force this variable to true...
boolean checkCommittedModel = (commands.length < 50);
for (Object cmd : commands) {
if (cmd == SOFTCOMMIT) {
assertU(commit("softCommit", "true"));
committedModel = new LinkedHashMap(model);
checkCommittedModel = true;
} else if (cmd == HARDCOMMIT) {
assertU(commit("softCommit", "false"));
committedModel = new LinkedHashMap(model);
checkCommittedModel = true;
} else {
assertNotNull("null command in checkReplay", cmd);
assertTrue("cmd is neither sentinal (HARD|SOFT)COMMIT object, nor Solr doc: " + cmd.getClass(), cmd instanceof SolrInputDocument);
final SolrInputDocument sdoc = (SolrInputDocument) cmd;
final int id = Integer.parseInt(sdoc.getFieldValue("id").toString());
final DocInfo previousInfo = model.get(id);
final Long previousValue = (null == previousInfo) ? null : previousInfo.value;
final long version = addAndGetVersion(sdoc, null);
final Object val = sdoc.getFieldValue(valField);
if (val instanceof Map) {
// atomic update of the field we're modeling
Map<String, ?> atomicUpdate = (Map) val;
assertEquals(sdoc.toString(), 1, atomicUpdate.size());
if (atomicUpdate.containsKey("inc")) {
// Solr treats inc on a non-existing doc (or doc w/o existing value) as if existing value is 0
final long base = (null == previousValue) ? 0L : previousValue;
model.put(id, new DocInfo(version, base + ((Number) atomicUpdate.get("inc")).longValue()));
} else if (atomicUpdate.containsKey("set")) {
model.put(id, new DocInfo(version, ((Number) atomicUpdate.get("set")).longValue()));
} else {
fail("wtf update is this? ... " + sdoc);
}
} else if (null == val) {
// the field we are modeling is not mentioned in this update, It's either...
//
// a) a regular update of some other fields (our model should have a null value)
// b) an atomic update of some other field (keep existing value in model)
//
// for now, assume it's atomic and we're going to keep our existing value...
Long newValue = (null == previousInfo) ? null : previousInfo.value;
for (SolrInputField field : sdoc) {
if (!("id".equals(field.getName()) || (field.getValue() instanceof Map))) {
// not an atomic update, newValue in model should be null
newValue = null;
break;
}
}
model.put(id, new DocInfo(version, newValue));
} else {
// regular replacement of the value in the field we're modeling
assertTrue("Model field value is not a Number: " + val.getClass(), val instanceof Number);
model.put(id, new DocInfo(version, ((Number) val).longValue()));
}
}
// RTG to check the values for every id against the model
for (Map.Entry<Integer, DocInfo> entry : model.entrySet()) {
final Long expected = entry.getValue().value;
assertEquals(expected, client.getById(String.valueOf(entry.getKey())).getFirstValue(valField));
}
// search to check the values for every id in the committed model
if (checkCommittedModel) {
final int numCommitedDocs = committedModel.size();
String[] xpaths = new String[1 + numCommitedDocs];
int i = 0;
for (Map.Entry<Integer, DocInfo> entry : committedModel.entrySet()) {
Integer id = entry.getKey();
Long expected = entry.getValue().value;
if (null != expected) {
xpaths[i] = "//result/doc[./str='" + id + "'][./long='" + expected + "']";
} else {
xpaths[i] = "//result/doc[./str='" + id + "'][not(./long)]";
}
i++;
}
xpaths[i] = "//*[@numFound='" + numCommitedDocs + "']";
assertQ(req("q", "*:*", "fl", "id," + valField, "rows", "" + numCommitedDocs), xpaths);
}
}
}
use of org.apache.solr.common.SolrInputField in project lucene-solr by apache.
the class JsonLoaderTest method testBigDecimalValuesInAdd.
@Test
public void testBigDecimalValuesInAdd() throws Exception {
String str = ("{'add':[{'id':'1','bd1':0.12345678901234567890123456789012345," + "'bd2':12345678901234567890.12345678901234567890,'bd3':0.012345678901234567890123456789012345," + "'bd3':123456789012345678900.012345678901234567890}]}").replace('\'', '"');
SolrQueryRequest req = req();
SolrQueryResponse rsp = new SolrQueryResponse();
BufferingRequestProcessor p = new BufferingRequestProcessor(null);
JsonLoader loader = new JsonLoader();
loader.load(req, rsp, new ContentStreamBase.StringStream(str), p);
assertEquals(1, p.addCommands.size());
AddUpdateCommand add = p.addCommands.get(0);
SolrInputDocument d = add.solrDoc;
SolrInputField f = d.getField("bd1");
assertTrue(f.getValue() instanceof String);
assertEquals("0.12345678901234567890123456789012345", f.getValue());
f = d.getField("bd2");
assertTrue(f.getValue() instanceof String);
assertEquals("12345678901234567890.12345678901234567890", f.getValue());
f = d.getField("bd3");
assertEquals(2, ((List) f.getValue()).size());
assertTrue(((List) f.getValue()).contains("0.012345678901234567890123456789012345"));
assertTrue(((List) f.getValue()).contains("123456789012345678900.012345678901234567890"));
req.close();
}
use of org.apache.solr.common.SolrInputField in project lucene-solr by apache.
the class AddUpdateCommand method getIndexedId.
/** Returns the indexed ID for this document. The returned BytesRef is retained across multiple calls, and should not be modified. */
public BytesRef getIndexedId() {
if (indexedId == null) {
IndexSchema schema = req.getSchema();
SchemaField sf = schema.getUniqueKeyField();
if (sf != null) {
if (solrDoc != null) {
SolrInputField field = solrDoc.getField(sf.getName());
int count = field == null ? 0 : field.getValueCount();
if (count == 0) {
if (overwrite) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Document is missing mandatory uniqueKey field: " + sf.getName());
}
} else if (count > 1) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Document contains multiple values for uniqueKey field: " + field);
} else {
BytesRefBuilder b = new BytesRefBuilder();
sf.getType().readableToIndexed(field.getFirstValue().toString(), b);
indexedId = b.get();
}
}
}
}
return indexedId;
}
use of org.apache.solr.common.SolrInputField in project lucene-solr by apache.
the class AddUpdateCommand method getHashableId.
/**
* @return String id to hash
*/
public String getHashableId() {
String id = null;
IndexSchema schema = req.getSchema();
SchemaField sf = schema.getUniqueKeyField();
if (sf != null) {
if (solrDoc != null) {
SolrInputField field = solrDoc.getField(sf.getName());
int count = field == null ? 0 : field.getValueCount();
if (count == 0) {
if (overwrite) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Document is missing mandatory uniqueKey field: " + sf.getName());
}
} else if (count > 1) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Document contains multiple values for uniqueKey field: " + field);
} else {
return field.getFirstValue().toString();
}
}
}
return id;
}
Aggregations