将世界上所有国家和城市存储在 Lucene 索引中是好还是坏?
Is storing all the countries and cities in the world in the Lucene index a good or bad idea?
我了解到,通过将我需要的字段存储在索引本身中,我可以在搜索实体时消除与数据库的往返。但是我也读到这会增加索引,经验法则是索引越小搜索速度越快。我想存储一个国家、一个城市和一个浮点数组。它涉及世界上所有的城市和国家。那么什么更快呢?将所有内容存储在索引中或从数据库中检索它们?
@Entity
@Indexed
public class Location implements Serializable {
@Id
@GeneratedValue(generator = "ID_GENERATOR")
private Long id;
@DocumentId(name = "_documentId")
@Field(store = Store.YES)
private String country;
@Field(store = Store.YES)
private String city;
@Field(store = Store.YES)
private String province;
@Field(store = Store.YES, index = Index.NO)
private final float[] temperatures = new float[12];
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public float[] getTemperatures() {
return temperatures;
}
}
此外,谁能告诉我 Hibernate 搜索预测或 Lucene 索引的确切存储位置?它们似乎不像 Elastic Search 那样存储为 JSON 文件。是否所有内容都存储在 RAM 内存中?
此致
这是好主意还是坏主意取决于很多因素。通常我希望它是个好主意,但这是假设您的数据库往返实际上很慢,并且跳过它有助于从数据库中承担一些负载以保持处理能力可用于其他查询。
虽然您可以通过启用 Hibernate 的二级缓存来实现相同的目标,但实际上您必须比较三种方法的权衡:
- 从 Lucene 索引加载它们
- 从 Hibernate ORM 二级缓存(堆内缓存)加载它们
- 使用 JDBC 连接从 RDBMS 加载
通常您可能希望限制 JVM 堆的大小以保持应用程序的响应速度并更容易调整 GC;这意味着二级缓存的大小是有限的,可能需要被其他数据点使用,这些数据点从智能驱逐算法中获益更多,适当的缓存可以提供。
在 Lucene 索引中存储是一种 all/nothing 方法,因此您做出的设计决策不会自动在内存使用和缓存命中有用性之间取得平衡...仍然 Lucene 索引通常存储在内存映射文件系统,因此您实际上受益于本机内存来缓存它,所以是的,只要有一些空闲 RAM 可用于此目的,您就会受益于 RAM。
简而言之:我认为值得一试,好处通常 很强。但是通过测量来验证它!
我了解到,通过将我需要的字段存储在索引本身中,我可以在搜索实体时消除与数据库的往返。但是我也读到这会增加索引,经验法则是索引越小搜索速度越快。我想存储一个国家、一个城市和一个浮点数组。它涉及世界上所有的城市和国家。那么什么更快呢?将所有内容存储在索引中或从数据库中检索它们?
@Entity
@Indexed
public class Location implements Serializable {
@Id
@GeneratedValue(generator = "ID_GENERATOR")
private Long id;
@DocumentId(name = "_documentId")
@Field(store = Store.YES)
private String country;
@Field(store = Store.YES)
private String city;
@Field(store = Store.YES)
private String province;
@Field(store = Store.YES, index = Index.NO)
private final float[] temperatures = new float[12];
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public float[] getTemperatures() {
return temperatures;
}
}
此外,谁能告诉我 Hibernate 搜索预测或 Lucene 索引的确切存储位置?它们似乎不像 Elastic Search 那样存储为 JSON 文件。是否所有内容都存储在 RAM 内存中?
此致
这是好主意还是坏主意取决于很多因素。通常我希望它是个好主意,但这是假设您的数据库往返实际上很慢,并且跳过它有助于从数据库中承担一些负载以保持处理能力可用于其他查询。
虽然您可以通过启用 Hibernate 的二级缓存来实现相同的目标,但实际上您必须比较三种方法的权衡:
- 从 Lucene 索引加载它们
- 从 Hibernate ORM 二级缓存(堆内缓存)加载它们
- 使用 JDBC 连接从 RDBMS 加载
通常您可能希望限制 JVM 堆的大小以保持应用程序的响应速度并更容易调整 GC;这意味着二级缓存的大小是有限的,可能需要被其他数据点使用,这些数据点从智能驱逐算法中获益更多,适当的缓存可以提供。
在 Lucene 索引中存储是一种 all/nothing 方法,因此您做出的设计决策不会自动在内存使用和缓存命中有用性之间取得平衡...仍然 Lucene 索引通常存储在内存映射文件系统,因此您实际上受益于本机内存来缓存它,所以是的,只要有一些空闲 RAM 可用于此目的,您就会受益于 RAM。
简而言之:我认为值得一试,好处通常 很强。但是通过测量来验证它!