我们的REST API允许用户将自定义无模式JSON添加到我们的一些REST资源中,我们需要它可以在Elasticsearch中进行搜索.这种自定义数据及其结构可以在相同类型的资源之间完全不同.
考虑这个示例文档:
{
"givenName": "Joe",
"username": "joe",
"email": "joe@mailinator.com",
"customData": {
"favoriteColor": "red",
"someObject": {
"someKey": "someValue"
}
}
}
Run Code Online (Sandbox Code Playgroud)
除customData遵守架构外的所有字段.customData始终是JSON对象,但该对象中的所有字段和值可能因资源而异.无法保证customData中的任何给定字段名称或值(甚至值类型)在任何两个资源中都是相同的,因为用户可以根据需要编辑这些字段.
支持搜索的最佳方法是什么?
我们认为解决方案是不创建customData索引创建时的任何映射,但随后它变得不可思议(这与ES文档所说的相反).如果对非映射属性的查询起作用,这将是理想的解决方案,并且此方法没有性能问题.但是,在针对该问题运行多个测试之后,我们无法使其工作.
这是需要任何特殊配置的东西吗?或者文档不正确?关于它为什么不起作用的一些澄清将不胜感激.
由于目前这不适合我们,我们已经考虑了几种替代解决方案:
重新索引:这将是昂贵的,因为我们需要重新索引包含该文档的每个索引,并且每次用户使用不同的值类型更新属性时都这样做.性能真的很糟糕,所以这可能不是一个真正的选择.
使用多匹配查询:我们将通过在每次customData对象发生更改时将随机字符串附加到customData字段名称来执行此操作.例如,这就是索引的文档看起来像:
{
"givenName": "Joe",
"username": "joe",
"email": "joe@mailinator.com",
"customData_03ae8b95-2496-4c8d-9330-6d2058b1bbb9": {
"favoriteColor": "red",
"someObject": {
"someKey": "someValue"
}
}
}
Run Code Online (Sandbox Code Playgroud)
这意味着ES将为每个"随机"字段创建一个新映射,我们将在执行查询时使用字段名称的"start with"通配符进行短语多匹配查询.例如:
curl -XPOST 'eshost:9200/test/_search?pretty' -d '
{
"query": {
"multi_match": {
"query" : "red",
"type" : "phrase",
"fields" : ["customData_*.favoriteColor"]
}
}
}' …Run Code Online (Sandbox Code Playgroud)当向 ActiveMQ 队列添加大量负载时,它似乎按预期将消息入队/出队,但存储仍然已满。
这会导致生产者在一段时间后(当存储达到 100% 时)阻塞,进而导致应用程序停止响应请求。
这是我们正在使用的相关 activeMQ Spring 配置:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
<!-- =====================================================
Broker Configuration
===================================================== -->
<broker id="appEmbeddedBroker"
xmlns="http://activemq.apache.org/schema/core"
brokerName="${msg.embedded.broker.name}"
persistent="true"
dataDirectory="${msg.embedded.broker.data.directory}"
useJmx="true" >
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry topic=">" >
<pendingMessageLimitStrategy>
<constantPendingMessageLimitStrategy limit="1000"/>
</pendingMessageLimitStrategy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
<managementContext>
<managementContext connectorPort="${msg.embedded.broker.jmx.port}" createConnector="false"/>
</managementContext>
<persistenceAdapter>
<levelDB directory="${msg.embedded.broker.db.directory}" />
</persistenceAdapter>
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="10"/>
</memoryUsage>
<storeUsage>
<storeUsage limit="${msg.embedded.broker.system.usage.store.usage}"/> <!-- Configured for 200Mb -->
</storeUsage>
<tempUsage>
<tempUsage limit="${msg.embedded.broker.system.usage.temp.usage}"/> <!-- Configured for 40Mb --> …Run Code Online (Sandbox Code Playgroud)