当前位置: 首页 > elasticsearch, 搜索 > 正文

elasticsearch 1.0.1版本创建mapping注意事项

1 星2 星3 星4 星5 星 (暂无评分)
Loading ... Loading ...
baidu_share

在使用elasticsearch 1.0.1版本创建索引和映射,再添加文档,查询时不返回结果(单个字可以),使用es-ik进行分词。该程序在0.90.1版本没有任何问题。

首先来看看程序创建索引:

	public static void createIndex(String indexName, String indexType) {
 
		Client esClient = ESServiceSingleton2.getTransportClient();
 
	    // 创建Mapping
	    XContentBuilder mapping =createMapping(indexName);
		// 创建一个空索引
		esClient.admin().indices().prepareCreate(indexName).execute().actionGet();
 
		PutMappingRequest mappingRequest = Requests.putMappingRequest(indexName).type(indexType).source(mapping);
 
		PutMappingRequestBuilder pmrb = esClient.admin().indices()
									.preparePutMapping(indexName)
									.setType(indexType).setSource(mapping);
		PutMappingResponse response = pmrb.execute().actionGet();			
		if (!response.isAcknowledged()) {
			System.out.println("Could not define mapping for type ["+indexName+"]/["+indexType+"].");
		} else {
			System.out.println("Mapping definition for ["+indexName+"]/["+indexType+"] succesfully created.");
		}
	}

mapping程序段:

	public static XContentBuilder createMapping(String indexName){
		XContentBuilder mapping = null;
		try {
			mapping = jsonBuilder()
					.startObject()
						// 索引库名(类似数据库中的表)
						.startObject(indexName)
							// 索引里面的字段
							//.field("dynamic","strict")
							.startObject("properties")
								// 新闻ID
								.startObject("id")
									.field("type", "long")
									.field("store", "yes")
									.field("index", "not_analyzed")
									.field("include_in_all", "false")
								.endObject()                              
								// 新闻标题
								.startObject("title")
									.field("type", "string")
									.field("store", "yes")
									.field("term_vector","with_positions_offsets")
									.field("indexAnalyzer", "ik")
									.field("searchAnalyzer", "ik")
									.field("include_in_all", "false")
									.field("boost", 4.0) // 打分(默认1.0)
								.endObject()                               
								// updatetime
								.startObject("updatetime")
									.field("type", "string")
									.field("store", "yes")
									.field("index", "not_analyzed")
									//.field("include_in_all", "false")
								.endObject()
 
							.endObject()
						.endObject()
					.endObject();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return mapping;
	}
}

获取elasticsearch client程序请参考:elasticsearch获取java client实例

main函数的实例为:

	public static void main(String[] args) {
		Client client = ESServiceSingleton2.getTransportClient();
 
		createIndex("test", "xq");
 
		client.close();
 
	}

执行main函数,用head 查看,选择test索引下面的”info”,选择”Index Metadata”,得到如下结果
error-mapping
发现得到mapping为空。上述代码在0.90.1版本完全正确。

经过一番检查,原来是创建mapping时,传递的参数错误,应该传递indexType,而不是indexName。

	public static XContentBuilder createMapping(String indexType){
		XContentBuilder mapping = null;
		try {
			mapping = jsonBuilder()
					.startObject()
						// 索引库名(类似数据库中的表)
						.startObject(indexType)
							// 索引里面的字段
							//.field("dynamic","strict")
							.startObject("properties")
								// 新闻ID
								.startObject("id")
									.field("type", "long")
									.field("store", "yes")
									.field("index", "not_analyzed")
									.field("include_in_all", "false")
								.endObject()                              
								// 新闻标题
								.startObject("title")
									.field("type", "string")
									.field("store", "yes")
									.field("term_vector","with_positions_offsets")
									.field("indexAnalyzer", "ik")
									.field("searchAnalyzer", "ik")
									.field("include_in_all", "false")
									.field("boost", 4.0) // 打分(默认1.0)
								.endObject()                               
								// updatetime
								.startObject("updatetime")
									.field("type", "string")
									.field("store", "yes")
									.field("index", "not_analyzed")
									//.field("include_in_all", "false")
								.endObject()
 
							.endObject()
						.endObject()
					.endObject();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return mapping;
	}
}

修改程序后,重新用head查看,得到正确的mapping。
success-mapping

在mapping映射为空时,elasticsearch添加文档时,会自动进行mapping。用head查看mapping结果:
auto-mapping
添加文档程序:

public static Integer addIndex(String indexName, String indexType) {
 
		Client esClient = ESServiceSingleton2.getTransportClient();
		//esClient.prepareIndex().setIndex(indexName).setType(indexType).setSource(createMapping(indexName)).execute().actionGet();
		BulkRequestBuilder bulkRequest = esClient.prepareBulk();
 
		try {
			bulkRequest.add(esClient.prepareIndex(indexName, indexType, "" + 1)
					.setSource(jsonBuilder()
							.startObject()
								.field("id", 1l)
								.field("title", "中国人民站起来了")
								.field("updatetime", "1370563200")
							.endObject()));
			bulkRequest.add(esClient.prepareIndex(indexName, indexType, "" + 2)
					.setSource(
							jsonBuilder().startObject().field("id", 2l)
 
							.field("title", "阿青多发点中国人民公共辐射的美丽汉中的交谈")
									.field("updatetime", "1350327958")
									.endObject()));
 
		} catch (Exception e) {
			e.printStackTrace();
		}
		bulkRequest.execute().actionGet();
 
		return bulkRequest.numberOfActions();
 
	}

查询程序:

	public static void query(String query) {
		Client client = ESServiceSingleton2.getTransportClient();
		QueryStringQueryBuilder qsqb = new QueryStringQueryBuilder(query);
		qsqb.analyzer("ik").field("title");
		client.admin().indices().prepareRefresh().execute().actionGet();
 
		SearchResponse searchResponse = client.prepareSearch("test")
				.setTypes("xq").setQuery(qsqb)
				// .setScroll(new TimeValue(60000))
				.addFields("id", "title", "updatetime")
				// .addSort("updatetime", SortOrder.DESC)
				.addSort("_score", SortOrder.DESC)
				// .addHighlightedField("title")
				.setHighlighterEncoder("UTF-8").execute().actionGet();
		// 搜索耗时
		Float usetime = searchResponse.getTookInMillis() / 1000f;
		// 命中记录数
		Long hits = searchResponse.getHits().totalHits();
		for (SearchHit hit : searchResponse.getHits()) {
			// 打分
			Float score = hit.getScore();
			Integer id = Integer.parseInt(hit.getFields().get("id").value()
					.toString());
 
			String title = hit.getFields().get("title").value().toString();
			System.out.println(title);
		}
 
	}

当自动mapping的时候,title: {type: string} 只有一个属性,查询程序制定analyzer为ik时,当然不会有任何结果。
把查询程序中qsqb.analyzer(“ik”).field(“title”)语句注释掉就会有结果了。
main函数的实例为:

	public static void main(String[] args) {
		Client client = ESServiceSingleton2.getTransportClient();
 
		createIndex("test", "xq");
                addIndex("test", "xq");
		query("中国");
		client.close();
 
	}

elasticsearch.yml使用index.mapper.dynamic : false 全局禁止自动mapping。
.field(“dynamic”,”strict”) 来局部禁止自动mapping。

本文固定链接: http://www.chepoo.com/elasticsearch-1-0-1-version-to-create-mapping-precautions.html | IT技术精华网

elasticsearch 1.0.1版本创建mapping注意事项:等您坐沙发呢!

发表评论