SOLR-139: update doc - create if it doesn't exist by default

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1361301 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2012-07-13 17:10:36 +00:00
parent 8d68f469cc
commit 732ad20130
3 changed files with 27 additions and 12 deletions

View File

@ -65,6 +65,11 @@ New Features
javax.script.ScriptEngineFactory
(Uri Boness, ehatcher, Simon Rosenthal, hossman)
* SOLR-139: Change to updateable documents to create the document if it doesn't
already exist. To assert that the document must exist, use the optimistic
concurrency feature by specifying a _version_ of 1. (yonik)
Bug Fixes
* SOLR-3582: Our ZooKeeper watchers respond to session events as if they are change events,

View File

@ -452,10 +452,7 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor {
if (leaderLogic) {
boolean updated = getUpdatedDocument(cmd);
if (updated && versionOnUpdate == -1) {
versionOnUpdate = 1; // implied "doc must exist" for now...
}
boolean updated = getUpdatedDocument(cmd, versionOnUpdate);
if (versionOnUpdate != 0) {
Long lastVersion = vinfo.lookupVersion(cmd.getIndexedId());
@ -517,7 +514,7 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor {
// TODO: may want to switch to using optimistic locking in the future for better concurrency
// that's why this code is here... need to retry in a loop closely around/in versionAdd
boolean getUpdatedDocument(AddUpdateCommand cmd) throws IOException {
boolean getUpdatedDocument(AddUpdateCommand cmd, long versionOnUpdate) throws IOException {
SolrInputDocument sdoc = cmd.getSolrInputDocument();
boolean update = false;
for (SolrInputField sif : sdoc.values()) {
@ -533,13 +530,17 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor {
SolrInputDocument oldDoc = RealTimeGetComponent.getInputDocument(cmd.getReq().getCore(), id);
if (oldDoc == null) {
// not found... allow this in the future (depending on the details of the update, or if the user explicitly sets it).
// could also just not change anything here and let the optimistic locking throw the error
throw new SolrException(ErrorCode.CONFLICT, "Document not found for update. id=" + cmd.getPrintableId());
// create a new doc by default if an old one wasn't found
if (versionOnUpdate <= 0) {
oldDoc = new SolrInputDocument();
} else {
// could just let the optimistic locking throw the error
throw new SolrException(ErrorCode.CONFLICT, "Document not found for update. id=" + cmd.getPrintableId());
}
} else {
oldDoc.remove(VERSION_FIELD);
}
oldDoc.remove(VERSION_FIELD);
for (SolrInputField sif : sdoc.values()) {
Object val = sif.getValue();
if (val instanceof Map) {

View File

@ -150,14 +150,23 @@ public class TestUpdate extends SolrTestCaseJ4 {
version = deleteAndGetVersion("1", null);
afterUpdate.call();
try {
// Currently, there is an implicit _version_=1 for updates (doc must exist). This is subject to change!
version2 = addAndGetVersion(sdoc("id","1", "val_is",map("add",-100)), null);
// test that updating a non-existing doc fails if we set _version_=1
version2 = addAndGetVersion(sdoc("id","1", "val_is",map("add",-101), "_version_","1"), null);
fail();
} catch (SolrException se) {
assertEquals(409, se.code());
}
// test that by default we can update a non-existing doc
version = addAndGetVersion(sdoc("id","1", "val_i",102, "val_is",map("add",-102)), null);
afterUpdate.call();
assertJQ(req("qt","/get", "id","1", "fl","id,val*")
,"=={'doc':{'id':'1', 'val_i':102, 'val_is':[-102]}}"
);
version = addAndGetVersion(sdoc("id","1", "val_i",5), null);
afterUpdate.call();