Java 将 multiValued 字段添加到 SolrInputDocument
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21438050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add multiValued field to a SolrInputDocument
提问by Sal81
We are using a solr embeded instance for Java SolrJ.
我们正在使用 Java SolrJ 的 solr 嵌入实例。
I want to add a multivalued field to a document. The multivalued field is a coma separated String.
我想向文档添加多值字段。多值字段是一个逗号分隔的字符串。
In Java I want to do:
在 Java 中,我想做:
solrInputDocument.addField(Field1, "value1,value2,value3");
The definition for Field1 in the schema is as follow
schema中Field1的定义如下
<field name="Field1" type="multiValuedField" indexed="true" stored="true" multiValued="true" required="false"/>
<fieldType name="multiValuedField" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.ClassicTokenizerFactory"/>
</analyzer>
</fieldType>
With this configuration we were expecting that when we invoke the addField method Solr was able to check that it is a multiValuedField and so it converts the String into an arrayList with the different values.
通过这种配置,我们期望当我们调用 addField 方法时,Solr 能够检查它是否是 multiValuedField,因此它将 String 转换为具有不同值的 arrayList。
Instead we are getting an arraylist with just one value that is in fact the original string added to the document.
相反,我们得到一个只有一个值的数组列表,它实际上是添加到文档中的原始字符串。
Question: should be the tokenizer taking care of this, or should we do it ourselves when we are adding multivalued fields to the document?
问题:分词器应该处理这个问题,还是应该在我们向文档添加多值字段时自己做?
Thanks.
谢谢。
回答by Jerome Diaz
As I am not using SOLRJ to add elements to SOLR I am not really sure, but I think you should have used
由于我没有使用 SOLRJ 向 SOLR 添加元素,因此我不确定,但我认为您应该使用
solrInputDocument.addField(Field1, "value1");
solrInputDocument.addField(Field1, "value2");
solrInputDocument.addField(Field1, "value3");
回答by benjammin
The addFieldmethod of SolrInputDocument accepts a string and an object. So to handle multivalued fields, you can pass in an ArrayList with your desired values for the second parameter, and SolrJ will update the multivalued field accordingly:
所述激活addFieldSolrInputDocument的方法接受字符串和一个对象。因此,要处理多值字段,您可以为第二个参数传入一个带有所需值的 ArrayList,SolrJ 将相应地更新多值字段:
String[] valuesArray = {"value1", "value2", "value3"};
ArrayList<String> values = new ArrayList<String>(Arrays.asList(valuesArray));
solrInputDocument.addField("Field1", values);
回答by Sal81
Confirmed. Tokenizers doesn't "cast" the data for you. So, the approach is to work on the data during the loading time, to have it in the proper format.
确认的。Tokenizers 不会为您“投射”数据。因此,方法是在加载期间处理数据,使其格式正确。
Thnks for your help.
谢谢你的帮助。
回答by jstricker
You can call SolrInputDocument.addField(String name, Object value)
either multiple times passing an Object
as the value or a single time passing a Collection
as the value.
您可以调用SolrInputDocument.addField(String name, Object value)
多次传递 aObject
作为值,也可以调用一次传递 aCollection
作为值。
Example #1:
示例#1:
ArrayList<String> values = Arrays.asList({"value1", "value2", "value3"});
solrInputDocument.addField("field", values);
Example #2:
示例#2:
solrInputDocument.addField("field", "value1");
solrInputDocument.addField("field", "value2");
solrInputDocument.addField("field", "value3");
Both of these examples will result in the same thing. You could even mix and match the calls if you needed to. To see why this works, trace the calls into the Solr source code and you'll find the multi-valued cases are handled in SolrInputField.addValue(Object v, float b)
.
这两个示例都将导致相同的结果。如果需要,您甚至可以混合和匹配呼叫。要了解其工作原理,请跟踪对 Solr 源代码的调用,您会发现多值情况在SolrInputField.addValue(Object v, float b)
.
/**
* Add values to a field. If the added value is a collection, each value
* will be added individually.
*/
@SuppressWarnings("unchecked")
public void addValue(Object v, float b) {
if( value == null ) {
if ( v instanceof Collection ) {
Collection<Object> c = new ArrayList<Object>( 3 );
for ( Object o : (Collection<Object>)v ) {
c.add( o );
}
setValue(c, b);
} else {
setValue(v, b);
}
return;
}
boost *= b;
Collection<Object> vals = null;
if( value instanceof Collection ) {
vals = (Collection<Object>)value;
}
else {
vals = new ArrayList<Object>( 3 );
vals.add( value );
value = vals;
}
// Add the new values to a collection
if( v instanceof Iterable ) {
for( Object o : (Iterable<Object>)v ) {
vals.add( o );
}
}
else if( v instanceof Object[] ) {
for( Object o : (Object[])v ) {
vals.add( o );
}
}
else {
vals.add( v );
}
}