0

来自:Hibernate Search Order by child-count 我有:

@Indexed
@Entity
public class TParent  implements java.io.Serializable {

.....
private Set<TChild> TChildSet = new HashSet<TChild>(0);

@ContainedIn
@FieldBridge(impl = CollectionCountBridge.class)
@Field(analyze = Analyze.NO)
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="TParent")
public Set<TChild> getTChildSet() {
   return this.TChildSet;
}

@Indexed
@Entity
public class TChild  implements java.io.Serializable {

.....
private TParent TParent;

@IndexedEmbedded
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="parent_id", nullable=false)
public TParent getTParent() {
    return this.TParent;
}

感谢 Don Roby,我已经应用了这个 CustomBridge

public class CollectionCountBridge extends IntegerBridge {

   @Override
   public String objectToString(Object object) {
     if (object == null || (!(object instanceof Collection))) {
         return null;
     }
     Collection<?> coll = (Collection<?>) object;
     int size = coll.size();
     System.out.println("col.size(): " + size);
     return super.objectToString(size);
  }

}

我正在列出 TParents。我正在尝试按 TChildSet 计数对它们进行排序。当我首先构建索引时,它可以完美运行。我可以列出 TParent 并按 TChild 的数量对它们进行排序。

FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery, TParent.class);
fullTextQuery.setSort(new Sort(new SortField("TChildSet", SortField.INT, true)));

现在...

当我添加一个新的 TChild 时,将执行 CustomBridge 代码。当我添加 TChild's 时,我希望看到排序发生变化。

我可以看到 TChild 计数增加了(根据 CustomBridge 代码中的 System.out.println())。

但是,查询没有正确排序它们。最初构建索引时的原始排序顺序仍然存在。添加新的 TChild 对排序顺序没有影响。我猜索引没有更新,但我不确定。

任何帮助或指示都会很棒。

非常感谢

约翰

编辑 直接的问题是索引中的值没有更新。这可以通过 Luke 看到。

4

2 回答 2

2

我认为您的问题是您将数字(整数)索引为字符串,但您想要数字排序。

你有两个选择。如果你坚持使用字符串方法,你将需要创建填充字符串(例如,如果你知道你永远不会有超过 100 个元素,你会填充所有数字,如 003 等)。这样,词汇排序将表现为数字排序。

可能更好的选择是将计数索引为数字字段。这样排序将自动为数字。类似(未经测试):

public class CollectionCountFieldBridge {

   void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
     if (object == null || (!(object instanceof Collection))) {
         return null;
     }
     Collection<?> coll = (Collection<?>) object;
     int size = coll.size();
     luceneOptions.addNumericFieldToDocument( name, value, document );;
   }
}
于 2013-09-18T10:24:04.947 回答
1

问题

在实体中,对不是数据库表字段的索引字段执行更新然后保存实体将不会导致索引更新。(保存实体并更新到作为数据库表字段的索引字段将导致索引自动更新)。

解决方案

(简单)手动更新索引

public static void addTChild() {
    Session session = null;
    try {
        session = HibernateUtil.getSession();
        session.beginTransaction();
        TParent tParent = (TParent)session.get(TParent.class, 6L);
        TChild tChild = new TChild(tParent, "Auto added " + new Date().toString(), 'y');
        Long id  = (Long)session.save(tChild);
        tChild = (TChild)session.get(TChild.class, id);
        tParent.getTChildSet().add(tChild);
        session.save(tParent);

        /*
         * Manually update the index.
         * Necessary due to fact that the index field updated
         * is not a DB table field and hence will not cause an index update
         */
        FullTextSession fullTextSession = Search.getFullTextSession(session);
        fullTextSession.index(tParent);

        session.getTransaction().commit();
    } catch (Exception ex) {
        session.getTransaction().rollback();
        ex.printStackTrace();
    } finally{
        if(session != null) {
            session.close();
        }
    }
}

实体:

/*
 * TParent
 */
@ContainedIn
@FieldBridge(impl = CollectionCountBridge.class)
@Field(analyze = Analyze.NO, store = Store.YES, name = "cCount")
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="TParent")
public List<TChild> getTChildSet() {
    return this.TChildSet;
}

和:

/*
 * TChild
 */
 @IndexedEmbedded
 @ManyToOne(fetch=FetchType.LAZY)
 @JoinColumn(name="parent_id", nullable=false)
 public TParent getTParent() {
    return this.TParent;
 }

据我所知,这就是它。

于 2013-09-24T13:23:30.683 回答