将日期范围添加到lucene搜索查询

时间:2015-12-26 15:47:40

标签: java lucene full-text-search hibernate-search date-range

我有一个lucene查询,可以对索引字段进行全文搜索。我想为此查询添加日期范围。

我发现了那个问题并在那里使用了答案: How to search between dates (Hibernate Search)?

但是当我想在日期之间获取数据时,它什么都不返回。 我使用的是MSSQL数据库,日期字段的类型是datetime。 但它在实体类中注释为@Temporal(TemporalType.TIMESTAMP)

这是我的实体类:

...
@Entity 
@Indexed
@FullTextFilterDef(name = "tarihAraligi", impl = Satislar.class)
@Table(name = "satislar")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Satislar.findAll", query = "SELECT s FROM Satislar s"),
@NamedQuery(name = "Satislar.findById", query = "SELECT s FROM Satislar s      WHERE s.id = :id"),
@NamedQuery(name = "Satislar.findByAdet", query = "SELECT s FROM Satislar s WHERE s.adet = :adet"),
@NamedQuery(name = "Satislar.findByTarih", query = "SELECT s FROM Satislar s WHERE s.tarih = :tarih"),
@NamedQuery(name = "Satislar.findByUrunadi", query = "SELECT s FROM Satislar s WHERE s.urunadi = :urunadi"),
@NamedQuery(name = "Satislar.findByMusteriadi", query = "SELECT s FROM Satislar s WHERE s.musteriadi = :musteriadi"),
@NamedQuery(name = "Satislar.findByUrunkategori", query = "SELECT s FROM Satislar s WHERE s.urunkategori = :urunkategori"),
@NamedQuery(name = "Satislar.findByUrunfiyat", query = "SELECT s FROM Satislar s WHERE s.urunfiyat = :urunfiyat"),
@NamedQuery(name = "Satislar.findByUrunalis", query = "SELECT s FROM Satislar s WHERE s.urunalis = :urunalis")})
public class Satislar implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@DocumentId
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@Column(name = "adet")
private int adet;
@Basic(optional = false)
@Column(name = "tarih")
@Temporal(TemporalType.TIMESTAMP)
private Date tarih;
@Basic(optional = false)
@Column(name = "urunadi")
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
private String urunadi;
@Basic(optional = false)
@Column(name = "musteriadi")
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
private String musteriadi;
@Basic(optional = false)
@Column(name = "urunkategori")
@Field(index=Index.YES, analyze=Analyze.NO, store=Store.NO)
private String urunkategori;
@Basic(optional = false)
@Column(name = "urunfiyat")
private int urunfiyat;
@Basic(optional = false)
@Column(name = "urunalis")
private int urunalis;
...

这是我进行全文搜索的地方:

fullTextSession.beginTransaction();

    QueryBuilder b = fullTextSession.getSearchFactory()
            .buildQueryBuilder().forEntity(Satislar.class).get();

    Query luceneQuery
            = b.keyword()
            .wildcard()
            .onFields(fields)
            .matching(kelime + "*")
             .createQuery();


   Query datequery = b
    .range()
        .onField( "tarih" ).ignoreFieldBridge()
        .from( DateTools.dateToString( new Date(2015, 12, 18 , 17, 40, 40), DateTools.Resolution.MILLISECOND ) )
        .to( DateTools.dateToString( new Date(2015, 12, 26 , 17, 40, 40), DateTools.Resolution.MILLISECOND ) ).excludeLimit()
        .createQuery();

    org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery(datequery);
    List<Satislar> kayitliSatislar = fullTextQuery.list();


    dtmSonuc.setRowCount(0);

    for (int i = 0; i < kayitliSatislar.size(); i++) {

        Satislar satis = kayitliSatislar.get(i);

        dtmSonuc.addRow(new String[]{satis.getMusteriadi(), satis.getUrunkategori(), satis.getUrunadi(),
            Integer.toString(satis.getAdet()), Integer.toString(satis.getUrunfiyat()), satis.getTarih().toString()});

    }

有2个不同的查询。一个在指定字段上进行全文通配符搜索,它可以工作。而另一个应该进行范围搜索,但它不起作用

我有3个问题:

1 - 我正在使用MSSQL db,日期字段的类型是datetime。 但它在实体类中注释为@Temporal(TemporalType.TIMESTAMP)。这是一个问题吗?

2 - 为什么范围搜索不起作用?

3 - 我可以将全文搜索与范围搜索相结合吗?

1 个答案:

答案 0 :(得分:1)

尝试将此注释添加到日期字段中:

@Basic(optional = false)
@Column(name = "tarih")
@Temporal(TemporalType.TIMESTAMP)
@DateBridge(resolution = Resolution.DAY)
private Date tarih;

如果仍然无效,请尝试使用Lucene本机查询:

TermRangeQuery luceneRangeDateQuery = new TermRangeQuery(fieldName, DateTools.dateToString(from, DateTools.Resolution.DAY), 
                DateTools.dateToString(to, DateTools.Resolution.DAY), true, true);

这始终有效。 (您可以将DateTools.Resolution.DAY更改为HOUR,SECOND,YEAR ......)