Lucene index: получение пустого результата во время запроса - PullRequest
0 голосов
/ 18 июня 2019

Я пытаюсь выполнить запрос с индексом Lucene, но получаю пустой результат и ошибки ниже в журнале,

Traversal query (query without index): select [jcr:path] from [nt:base] where isdescendantnode('/test') and name='World'; consider creating an index


[async] The index update failed
org.apache.jackrabbit.oak.api.CommitFailedException: OakAsync0002: Missing index provider detected for type [counter] on index [/oak:index/counter]


Я использую RDB DocumentStore и проверил, что индекс и узел созданы в таблице узлов. Я попробовал приведенный ниже код,

   @Autowired 
   NodeStore rdbNodeStore;

   //create reposiotory
   LuceneIndexProvider provider = new LuceneIndexProvider();
   ContentRepository repository = new Oak(rdbNodeStore)
                .with(new OpenSecurityProvider())
                .with(new InitialContent())
                .with((QueryIndexProvider) provider)
                .with((Observer) provider)
                .with(new LuceneIndexEditorProvider())
                .withAsyncIndexing("async", 
   5).createContentRepository();

    //login reposiotory and retrive session
    ContentSession contentSession = repository.login(null, null);
    Root root = contentSession.getLatestRoot();

    //create lucene index
      Tree index = root.getTree("/");

      Tree t = index.addChild("oak:index");

      t = t.addChild("lucene");
      t.setProperty("jcr:primaryType", "oak:QueryIndexDefinition", Type.NAME);
      t.setProperty("compatVersion", Long.valueOf(2L), Type.LONG);
      t.setProperty("type", "lucene", Type.STRING);
      t.setProperty("async", "async", Type.STRING);

      t = t.addChild("indexRules");
      t = t.addChild("nt:base");
      Tree propnode = t.addChild("properties");
      Tree t1 = propnode.addChild("name");
      t1.setProperty("name", "name");
      t1.setProperty("propertyIndex", Boolean.valueOf(true), Type.BOOLEAN);
      root.commit();

      //Create TestNode
      String h = "Hello" + System.currentTimeMillis();
      String w = "World" + System.currentTimeMillis();

      Tree test = root.getTree("/").addChild("test");
      test.addChild("a").setProperty("name", Arrays.asList(new String[] { h, w }), Type.STRINGS);
      test.addChild("b").setProperty("name", h);
      root.commit();

      //Search
      String query = "select [jcr:path] from [nt:base] where isdescendantnode('/test') and name='World' option(traversal ok)";

      List<String> paths = executeQuery(root, query, "JCR-SQL2", true, false);
      for (String path : paths) {
        System.out.println("Path=" + path);
      }

Может кто-нибудь поделиться примером кода о том, как создать индекс Lucene?

1 Ответ

0 голосов
/ 21 июня 2019

Есть несколько проблем с тем, что вы, вероятно, делаете.Первым делом будет ошибка, которую вы наблюдаете.Так как вы используете InitialContent, который обеспечивает индекс с type="counter".Для этого вам нужно иметь .with(new NodeCounterEditorProvider()) при создании хранилища.Это должно избежать ошибки, которую вы видите.

Но ваш код, скорее всего, все равно не будет работать, потому что индексы lucene являются асинхронными (что вы правильно настроили).Из-за этого асинхронного поведения вы не можете делать запросы сразу после добавления узла.Я попробовал ваш код, но мне пришлось добавить что-то вроде Thread.sleep(10*1000), прежде чем отправлять запросы.

В качестве еще одного примечания, я бы порекомендовал вам попробовать IndexDefinitionBuilder, чтобы создать структуру индекса lucene.Таким образом, вы можете заменить Tree index = root.getTree ("/");

Tree t = index.addChild("oak:index");

t = t.addChild("lucene");
t.setProperty("jcr:primaryType", "oak:QueryIndexDefinition", Type.NAME);
t.setProperty("compatVersion", Long.valueOf(2L), Type.LONG);
t.setProperty("type", "lucene", Type.STRING);
t.setProperty("async", "async", Type.STRING);

t = t.addChild("indexRules");
t = t.addChild("nt:base");
Tree propnode = t.addChild("properties");
Tree t1 = propnode.addChild("name");
t1.setProperty("name", "name");
t1.setProperty("propertyIndex", Boolean.valueOf(true), Type.BOOLEAN);
root.commit();

на

IndexDefinitionBuilder idxBuilder = new IndexDefinitionBuilder();
idxBuilder.indexRule("nt:base").property("name").propertyIndex();
idxBuilder.build(root.getTree("/").addChild("oak:index").addChild("lucene"));
root.commit();

Последний подход, imo, менее подвержен ошибкам и более редабален.

...